// Pack At: 2022-07-22 21:23:05
// ============================================================
// OUTPUT TARGET IMPORTS
// ============================================================
(function(){
window.TI_PACK_EXPORTS = {};
// ============================================================
// LV1 : imports
// ============================================================
// ============================================================
// LV2 : imports - (0)
// ============================================================
// ============================================================
// EXPORT 'm-my-buildsrv-actions.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['mod/buildsrv/m-my-buildsrv-actions.mjs'] = (function(){
////////////////////////////////////////////
function API_URL({ apiBase } = {}, path) {
  return Ti.Util.appendPath(apiBase, path)
}
////////////////////////////////////////////
const _M = {
  //----------------------------------------
  async createNewBuild({ commit, dispatch, rootState }, build) {
    if (!build) {
      return
    }
    let url = API_URL(rootState, "thing/create")
    let reo = await Ti.Http.post(url, {
      params: {
        ticket: rootState.auth.ticket,
        ts: "buildsrv"
      },
      body: JSON.stringify(_.assign(build, {
        build_stat: 0,
        user_id: rootState.auth.me.OID.myId,
        dev_tp: "air101"
      })),
      as: "json"
    })

    commit("setStatus", { reloading: true })
    await dispatch("reloadMyBuildList")
    commit("setCurrentBuildId", reo.id)
    await dispatch("reloadCurrentBuildConf")
    await dispatch("reloadCurrentBuildDataFile")
    await dispatch("reloadCurrentBuildDest")
    commit("setStatus", { reloading: false })

    commit("syncStatusChanged")
  },
  //----------------------------------------
  async removeCurrentBuild({ state, commit, dispatch, rootState }) {
    let buildId = state.currentBuildId
    if (!buildId) {
      return
    }
    let url = API_URL(rootState, "thing/delete")
    await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket,
        ts: "buildsrv",
        id: buildId,
        hard: true
      }
    })

    commit("setStatus", { reloading: true })
    await dispatch("reloadMyBuildList")
    commit("setCurrentBuildId", null)
    dispatch("autoSelectCurrentBuild")
    await dispatch("reloadCurrentBuildConf")
    await dispatch("reloadCurrentBuildDataFile")
    await dispatch("reloadCurrentBuildDest")

    commit("setStatus", { reloading: false })
    commit("syncStatusChanged")
  },
  //----------------------------------------
  async saveCurrentBuildConf({ commit, state, rootState }) {
    if (!state.currentBuildId) {
      return await Ti.Toast.Open("没有选择任何构建项目", "warn")
    }
    let content = state.currentBuildConf
    commit("setStatus", { saving: true })
    let url = API_URL(rootState, "/build/save_conf")
    await Ti.Http.post(url, {
      params: {
        ticket: rootState.auth.ticket,
        bid: state.currentBuildId
      },
      body: content || "",
      as: "json"
    })
    commit("setStatus", { saving: false })
    commit("setCurrentBuildConf", content)
    commit("setCurrentBuildSavedConf", content)
    commit("syncStatusChanged")
  },
  //----------------------------------------
  async updateCurrentBuild({ state, commit, dispatch, rootState }, data = {}) {
    let buildId = state.currentBuildId
    if (!buildId || !state.currentBuild || _.isEmpty(data)) {
      return
    }
    // 如果改变状态，看看是否需要保存
    // 需要保存一下配置文件
    // @see build_service.md
    if (state.status.changed && 1 == data.build_stat) {
      await dispatch("saveCurrentBuildConf")
    }

    // 如果改变状态为【排队中】，需要确保编译配置有内容，且选择了模块
    // 如果确定可以排队，那么需要先清除一下编译结果
    if (1 == data.build_stat) {
      let cbc = _.trim(state.currentBuildConf)
      if (!cbc) {
        return await Ti.Toast.Open("未初始化编译设置", "warn")
      }
      if (cbc.chip) {
        return await Ti.Toast.Open("未指定模块", "warn")
      }

      await dispatch("cleanCurrentBuildDest")
    }

    // 更新构建元数据
    let url = API_URL(rootState, "thing/update")
    await Ti.Http.post(url, {
      params: {
        ticket: rootState.auth.ticket,
        ts: "buildsrv",
        id: buildId
      },
      body: JSON.stringify(data)
    })

    commit("setStatus", { reloading: true })
    await dispatch("reloadMyBuildList")
    commit("setCurrentBuildId", null)
    dispatch("autoSelectCurrentBuild")
    await dispatch("reloadCurrentBuildConf")
    await dispatch("reloadCurrentBuildDest")

    commit("setStatus", { reloading: false })
    commit("syncStatusChanged")
  },
  //----------------------------------------
  updateCurrentBuildConf({ state, commit }, input) {
    //console.log("updateCurrentBuildConf", input)
    if (!state.currentBuildId) {
      console.warn("buildsrv mod: updateCurrentBuildConf but without currentBuildId!!");
      return;
    }
    let data = input || {}

    // 得到当前的模块类型
    let chip = data.chip || "air101"
    let metaName = `${chip}.meta.json`
    let bm = _.find(state.buildMetas, ({ nm }) => {
      return nm == metaName
    })
    let buildMeta = _.get(bm, "content") || {}

    // 得到 SDK 列表
    let presets = _.get(buildMeta, "builder.sdk.presets")
    let preset = _.find(presets, ({ name }) => name == data.sdkName)
    let sdk = _.get(preset, "value")

    // 处理两段式 ID
    let buildId = state.currentBuildId
    let pos = buildId.indexOf(":")
    if (pos > 0) {
      buildId = buildId.substring(pos + 1).trim()
    }

    // 更新默认值
    _.assign(data, {
      id: buildId,
      version: _.get(buildMeta, "version"),
      chip,
      sdk
    })
    commit("setCurrentBuildConf", data)
    commit("syncStatusChanged")
  },
  //----------------------------------------
  autoSelectCurrentBuild({ state, commit }) {
    // 从本地恢复
    let buildId = Ti.Storage.session.getString("minke-build-shop-current-build")
    // Select the first project
    if (!buildId) {
      let first = _.first(state.myBuildList)
      buildId = _.get(first, "id")
    }
    commit("setCurrentBuildId", buildId)
  },
  //----------------------------------------
  async reloadCurrentBuildConf({ commit, state, rootState }) {
    let { currentBuildId, currentBuild } = state
    if (!currentBuild) {
      commit("setCurrentBuildConf", null)
      return
    }

    // Reload content
    commit("setCurrentBuildConf")
    commit("setStatus", { reloading: true })
    let url = API_URL(rootState, "/build/read_conf")
    let reo = await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket,
        bid: currentBuildId
      }
    })
    commit("setStatus", { reloading: false })
    commit("setCurrentBuildConf", reo)
    commit("setCurrentBuildSavedConf", reo)
  },
  //----------------------------------------
  async reloadCurrentBuildDataFile({ commit, state, rootState }) {
    let { currentBuildId, currentBuild } = state
    if (!currentBuild) {
      commit("setCurrentBuildConf", null)
      return
    }

    // Reload content
    commit("setCurrentBuildDataFile")
    commit("setStatus", { reloading: true })
    let url = API_URL(rootState, "/build/get_data_file")
    let reo = await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket,
        bid: currentBuildId
      },
      as: "json"
    })
    commit("setStatus", { reloading: false })
    commit("setCurrentBuildDataFile", reo)
  },
  //----------------------------------------
  async removeCurrentBuildDataFile({ commit, state, dispatch, rootState }) {
    let { currentBuildId, currentBuild } = state
    if (!currentBuild) {
      commit("setCurrentBuildConf", null)
      return
    }

    // Reload content
    commit("setStatus", { reloading: true })
    let url = API_URL(rootState, "/build/del_data_file")
    let reo = await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket,
        bid: currentBuildId
      },
      as: "json"
    })
    await dispatch("reloadCurrentBuildDataFile")
    commit("setStatus", { reloading: false })
  },
  //----------------------------------------
  async cleanCurrentBuildDest({ commit, state, dispatch, rootState }) {
    let { currentBuildId, currentBuild } = state
    if (!currentBuild) {
      commit("setCurrentBuildConf", null)
      return
    }

    // Reload content
    let url = API_URL(rootState, "/build/clean_dest")
    await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket,
        bid: currentBuildId
      },
      as: "json"
    })
  },
  //----------------------------------------
  async reloadCurrentBuildDest({ commit, state, rootState }) {
    let { currentBuildId, currentBuild } = state
    if (!currentBuild) {
      commit("setCurrentBuildDest", null)
      return
    }

    // Reload content
    commit("setCurrentBuildDest")
    commit("setCurrentBuildLog")

    commit("setStatus", { reloading: true })
    let url_dest = API_URL(rootState, "/build/get_dest")
    let oDest = await Ti.Http.get(url_dest, {
      params: {
        ticket: rootState.auth.ticket,
        bid: currentBuildId
      },
      as: "json"
    })

    let url_log = API_URL(rootState, "/build/get_build_log")
    let oLog = await Ti.Http.get(url_log, {
      params: {
        ticket: rootState.auth.ticket,
        bid: currentBuildId
      },
      as: "json"
    })
    commit("setStatus", { reloading: false })
    commit("setCurrentBuildDest", oDest)
    commit("setCurrentBuildLog", oLog)
  },
  //----------------------------------------
  async reloadCurrentBuildLog({ commit, state, rootState }) {
    let { currentBuildId, currentBuild } = state
    if (!currentBuild) {
      commit("setCurrentBuildDest", null)
      return
    }

    // Reload content
    commit("setCurrentBuildDest")
    commit("setStatus", { reloading: true })
    let url = API_URL(rootState, "/build/get_build_log")
    let reo = await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket,
        bid: currentBuildId
      },
      as: "json"
    })
    commit("setStatus", { reloading: false })
    commit("setCurrentBuildLog", reo)
  },
  //----------------------------------------
  async reloadBuildMetas({ commit, state, rootState }) {
    let url = API_URL(rootState, "/build/metas")
    commit("setStatus", { reloading: true })
    let reo = await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket
      },
      as: "json"
    })
    commit("setStatus", { reloading: false })
    commit("setBuildMetas", reo)
  },
  //----------------------------------------
  async reloadMyBuildList({ commit, rootState }) {
    let url = API_URL(rootState, "/thing/list")
    let uid = _.get(rootState, "auth.me.OID.myId")
    commit("setStatus", { reloading: true })
    let reo = await Ti.Http.get(url, {
      params: {
        ts: "buildsrv",
        m: {
          "user_id": uid
        },
        s: {
          ct: -1
        }
      },
      as: "json"
    })
    commit("setStatus", { reloading: false })
    commit("setMyBuildList", reo)
  },
  //----------------------------------------
  async reload({ commit, dispatch }) {
    commit("setStatus", { reloading: true })

    await dispatch("reloadBuildMetas")
    await dispatch("reloadMyBuildList")

    dispatch("autoSelectCurrentBuild")

    await dispatch("reloadCurrentBuildConf")
    await dispatch("reloadCurrentBuildDataFile")
    await dispatch("reloadCurrentBuildDest")

    commit("setStatus", { reloading: false })
  }
  //----------------------------------------
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-stage-crumb.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/stage/lvgl-maker-stage-crumb.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    StageCrumbData() {
      // 设备是第一个
      let list = [{
        icon: "zmdi-devices",
        text: "设备",
        cancelBubble: true
      }]
      let hasCurrentBlock = this.LvglCurrentBlock ? true : false
      // 然后是当前屏幕
      if (this.LvglCurrentScreen) {
        list.push({
          icon: "zmdi-desktop-windows",
          text: this.LvglCurrentScreen.name,
          cancelBubble: true,
          eventName: hasCurrentBlock
        })
      }
      // 木有就退出咯
      else {
        return list
      }

      if (hasCurrentBlock) {
        // 然后是绘制父控件轴
        for (let blockName of this.LvglCurrentBlock.axis) {
          let it = this.genCrumbItemFromBlockName(blockName)
          if (it) {
            list.push(it)
          }
        }
        // 最后是自己
        let item = this.genCrumbItemFromBlockName(this.currentBlockName);
        if (item) {
          list.push(item)
        }
      }

      return list;
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    OnCrumbItemActived({ value }) {
      //console.log("OnCrumbItemActived", value)
      this.OnSelectBlockItem({ name: value });
    },
    //--------------------------------------
    genCrumbItemFromBlockName(blockName) {
      // 获取控件类型
      let comType = _.get(this.schema, `${blockName}.comType`)

      // 获取控件配置信息
      let comInfo = _.get(this.comSetups, comType)
      if (comInfo) {
        let { icon, title } = comInfo
        return {
          icon,
          text: `${title}(${blockName})`,
          value: blockName,
          cancelBubble: true,
          eventName: blockName != this.currentBlockName
        }
      }
    }
    //--------------------------------------
  }
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'devdetail.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/devdetail/devdetail.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props : {
    "value": {
      type: Array,
      default: ()=>[]
    },
    "lang": {
      type: String,
      default: "en_us"
    }
  },
  //////////////////////////////////////////
  computed : {
    //--------------------------------------
    TopClass() {
      return this.getTopClass()
    },
    //--------------------------------------
    DevGisData() {
      let list = []
      _.forEach(this.value, it=>{
        list.push({
          nm : it.nm,
          title : it.title,
          lng : it.lng,
          lat : it.lat
        })
      })
      return list
    },
    //--------------------------------------
    DevTrackHref() {return `${this.base}${this.lang}/my/devtrack.html?nm=\${nm}`},
    DevLogsHref() {return `${this.base}${this.lang}/my/devlog.html?nm=\${nm}`},
    //--------------------------------------
    DevMarkerPopup() {
      return {
        "设备名称:" : "=title",
        "设备编号:" : "=nm",
        "设备轨迹:" : `-><a target="_blank" href="${this.DevTrackHref}"><i class="fas fa-map-marked-alt"></i> 查看轨迹</a>`,
        "设备日志:" : `-><a target="_blank" href="${this.DevLogsHref}"><i class="fas fa-file-alt"></i> 查看日志</a>`
      }
    },
    //--------------------------------------
    DevMarkerPopupOptions() {
      return {
        offset: [0, -40],
        className: "dev-popup"
      }
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods : {
    //--------------------------------------
    //--------------------------------------
  }
  //////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-page.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/page/lvgl-page.mjs'] = (function(){
// 控件行为文档： https://doc.openluat.com/wiki/21?wiki_page_id=2566
const _M = {
  ///////////////////////////////////////////////
  props: {
    "adjustLayout": {
      type: Function
    },
    //-------------------------------------------
    // Behaviors
    //-------------------------------------------
    "layout": {
      type: String,
      default: "LAYOUT_OFF",
      validator: v => /^LAYOUT_(OFF|CENTER|GRID|COLUMN_(LEFT|MID|RIGHT)|(ROW|PRETTY)_(TOP|MID|BOTTOM))$/.test(v)
    },
    "fit": {
      type: String,
      default: "FIT_NONE",
      validator: v => /^FIT_(NONE|TIGHT|PARENT|MAX)$/.test(v)
    },
    "scrlbarMode": {
      type: String,
      default: "SCRLBAR_MODE_AUTO",
      validator: v => /^SCRLBAR_MODE_(AUTO|ON|DRAG|AUTO|HIDE|UNHIDE)$/.test(v)
    },
    "edgeFlash": {
      type: Boolean,
      default: false
    },
    //-------------------------------------------
    // Aspec
    //-------------------------------------------
    "defaultStatus": {
      type: Object,
      default: undefined,
    },
    //-------------------------------------------
    // Measure
    //-------------------------------------------

  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    CurrentStyle() {
      return _.get(this.defaultStatus, "bgPart") || {}
    },
    //-------------------------------------------
    PartMainStyle() {
      let css = {};
      //.........................................
      //this.setCssPad(css, this.CurrentStyle.pad);
      this.setCssBackgroundStyle(css, this.CurrentStyle.bg);
      this.setCssBorder(css, this.CurrentStyle.border);
      //.........................................
      return css;
    },
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    doAdjustLayout() {
      this.adjustLayout({
        autoFit: this.fit,
        layout: this.layout,
        scrollMode: this.scrlbarMode,
        padding: this.CurrentStyle.pad
      })
    },
    //-------------------------------------------
    tryAdjustLayout(newVal, oldVal) {
      //console.log("tryAdjustLayout", this.tiComId)
      if (!_.isEqual(newVal, oldVal)) {
        //console.log("doAdjustLayout")
        this.doAdjustLayout()
      }
    }
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  watch: {
    "layout": {
      handler: "tryAdjustLayout",
      immediate: true
    },
    "fit": {
      handler: "tryAdjustLayout",
      immediate: true
    },
    "scrlbarMode": {
      handler: "tryAdjustLayout",
      immediate: true
    },
    "CurrentStyle": {
      handler: "tryAdjustLayout",
      immediate: true
    }
  }
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-style-value.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/style/value/lvgl-maker-style-value.mjs'] = (function(){
////////////////////////////////////////////////////////
const _M = {
  //////////////////////////////////////////////////////
  props: {
    //-----------------------------------
    // Data
    //-----------------------------------
    value: {
      type: Object,
    },
  },
  //////////////////////////////////////////////////////
  computed: {
    //--------------------------------------------------
    StyleForm() {
      return {
        spacing: "tiny",
        fields: [
          {
            title: "文字内容",
            name: "str",
            comType: "TiInputText",
          },
          {
            title: "显示样式",
          },
          {
            title: "颜色",
            name: "color",
            comType: "TiInputColor",
            comConf: {
              showAlpha: false,
            },
          },
          {
            title: "不透明度",
            name: "opa",
            type: "Integer",
            defaultAs: 255,
            comType: "TiInputNum",
            comConf: {
              step: 1,
              minValue: 0,
              maxValue: 255,
            },
          },
          {
            title: "字间距",
            name: "letterSpace",
            type: "Integer",
            comType: "TiInputNum",
            comConf: {
              placeholder: 0,
            },
          },
          {
            title: "行间距",
            name: "lineSpace",
            type: "Integer",
            comType: "TiInputNum",
            comConf: {
              placeholder: 0,
            },
          },
          {
            title: "排列",
            name: "align",
            defaultAs: "CENTER",
            comType: "TiSwitcher",
            comConf: {
              options: ["LEFT", "CENTER", "RIGHT"],
            },
          },
          {
            title: "X轴位移",
            name: "ofsX",
            type: "Integer",
            comType: "TiInputNum",
            comConf: {
              placeholder: 0,
            },
          },
          {
            title: "Y轴位移",
            name: "ofsY",
            type: "Integer",
            comType: "TiInputNum",
            comConf: {
              placeholder: 0,
            },
          },
          {
            title: "高级设置",
          },
          {
            title: "字体",
            name: "font",
            comType: "TiInput",
          },
          {
            title: "混合模式",
            name: "blendMode",
            comType: "TiSwitcher",
            comConf: {
              options: ["NORMAL", "ADDITIVE", "SUBTRACTIVE"],
            },
          },
        ],
      };
    },
    //--------------------------------------------------
  },
  //////////////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-calendar.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/calendar/lvgl-calendar.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    todayDate: {
      type: String,
      default: "",
    },
    showedDate: {
      type: String,
      default: "",
    },
    highlightedDates: {
      type: Array,
      default() {
        return [];
      },
    },
    dayNames: {
      type: Array,
      default() {
        return [];
      },
    },
    monthNames: {
      type: Array,
      default() {
        return [];
      },
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    zoomScale: {
      type: Number,
      default: 1,
    },
  },
  ///////////////////////////////////////////////
  computed: {
    calendarFontZoom() {
      return this.zoomScale * 0.75;
    },
    CurrBgStyle() {
      return _.get(this.defaultStatus, "bgPart") || {};
    },
    CurrHeaderStyle() {
      return _.get(this.defaultStatus, "headerPart") || {};
    },
    CurrNamesStyle() {
      return _.get(this.defaultStatus, "dayNamesPart") || {};
    },
    calendarBgStyle() {
      let css = {};
      this.setCssBackgroundStyle(css, this.CurrBgStyle.bg || {});
      return css;
    },
    calendarHeaderStyle() {
      let css = {};
      this.setCssText(css, this.CurrHeaderStyle.text, this.calendarFontZoom);
      return css;
    },
    calendarNamesStyle() {
      let css = {};
      this.setCssText(css, this.CurrNamesStyle.text, this.calendarFontZoom);
      return css;
    },
    calendarDateDefaultStyle() {
      let css = {};
      this.setCssText(
        css,
        this.CurrDatesStyle("default").text,
        this.calendarFontZoom
      );
      return css;
    },
    calendarDateTodayStyle() {
      let css = {};
      this.setCssText(
        css,
        this.CurrDatesStyle("focused").text,
        this.calendarFontZoom
      );
      return css;
    },
    calendarDateHighlightedStyle() {
      let css = {};
      this.setCssText(
        css,
        this.CurrDatesStyle("checked").text,
        this.calendarFontZoom
      );
      return css;
    },
    showedYearMonth() {
      let year, month;
      if (this.showedDate) {
        year = parseInt(this.showedDate.substr(0, 4));
        month = parseInt(this.showedDate.substr(5, 2));
      } else {
        let cday = new Date();
        year = cday.getFullYear();
        month = 1;
      }
      return {
        year,
        month,
      };
    },
    today() {
      if (this.todayDate) {
        return this.todayDate;
      }
      let cday = new Date();
      let y = cday.getFullYear();
      let m = cday.getMonth() + 1;
      let d = cday.getDate();
      return `${y}-${m < 10 ? "0" + m : m}-${d < 10 ? "0" + d : d}`;
    },
    year() {
      let t = this.today;
      return parseInt(t.substr(0, 4));
    },
    month() {
      let t = this.today;
      return parseInt(t.substr(5, 2));
    },
    date() {
      let t = this.today;
      return parseInt(t.substr(8, 2));
    },
    dateGrid() {
      let sym = this.showedYearMonth;
      let dg = this.dateList(sym.year, sym.month);
      return dg;
    },
    dayNamesText() {
      if (this.dayNames.length == 7) {
        let ndns = [].concat(this.dayNames);
        let su = ndns.pop();
        ndns.unshift(su);
        return ndns;
      }
      return ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
    },
    monthNamesText() {
      if (this.monthNames.length == 12) {
        return this.monthNames;
      }
      return [
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "Novermber",
        "December",
      ];
    },
    monthText() {
      let sym = this.showedYearMonth;
      return this.monthNamesText[sym.month - 1];
    },
  },
  ///////////////////////////////////////////////
  methods: {
    CurrDatesStyle(state) {
      let dpart = _.get(this.defaultStatus, "datePart") || {};
      return dpart[state + "Status"] || {};
    },
    calDateStyle(di) {
      let hasHl = this.highlightedDates && this.highlightedDates.length > 0;
      let css = {};
      if (this.todayDate && di.allDate == this.today) {
        css = this.calendarDateTodayStyle;
      } else if (
        hasHl &&
        this.highlightedDates.find((hd) => {
          return hd == di.allDate;
        })
      ) {
        {
          css = this.calendarDateHighlightedStyle;
        }
      } else if (this.month == di.month) {
        css = this.calendarDateDefaultStyle;
      }
      return css;
    },
    calDateClz(di) {
      let hasHl = this.highlightedDates && this.highlightedDates.length > 0;
      let clz = "cal-date-item ";
      clz += di.month == this.month ? "curr-month " : "";
      if (this.todayDate && di.allDate == this.today) {
        clz += di.allDate == this.today ? "is-today " : "";
      } else if (
        hasHl &&
        this.highlightedDates.find((hd) => {
          return hd == di.allDate;
        })
      ) {
        clz += "is-hlday";
      }
      return clz;
    },
    dateList(year, month) {
      // ret保存生成好函数要返回的日期,
      var ret = [];
      // 如果没有传入 年月,自动获取当前的年月
      if (!year || !month) {
        var today = new Date();
        year = today.getFullYear();
        month = today.getMonth() + 1;
      }

      var firstDay = new Date(year, month - 1, 1); // 获取当月的第一天;
      var firstDayweekDay = firstDay.getDay(); // 当月的1号是星期几;(0到6之间)

      var lastDayOfLastMonth = new Date(year, month - 1, 0); // 上个月的最后一天;实例;
      var lastDateOfLastMonth = lastDayOfLastMonth.getDate(); // 上个月最后一天 具体日期

      var lastDay = new Date(year, month, 0); // 当月的最后一天;
      var lastDate = lastDay.getDate(); // 当月的最后一天是星期几

      // 要显示几个上个月的日期;如值为0则表示要显示0个上个月的日期,此时当月1日为周日
      var preMonthDayCount = firstDayweekDay; // 此处就不用减1;

      // 循环日历的42个格子
      for (var i = 0; i < 7 * 6; i++) {
        // preMonthDayCount如果为6,则表示要显示上月个6天的数据,也就是说i等于6的时候才是当月的第一天(即date==1)
        // preMonthDayCount如果为5,则表示要显示上月个5天的数据,也就是说i等于5的时候才是当月的第一天(即date==1)
        // preMonthDayCount如果为1,则表示要显示上月个1天的数据,也就是说i等于1的时候才是当月的第一天(即date==1)
        // 所以得出 date = i+1 - preMonthDayCount公式
        var date = i + 1 - preMonthDayCount;
        var showDate = date;
        var thisMonth = month;

        // 计算 上个月的日期;
        if (date <= 0) {
          thisMonth = month - 1; // 上个月的月份
          showDate = lastDateOfLastMonth + date; // 上个月的真实日期
        } else if (date > lastDate) {
          // 计算 下个月的日期;
          thisMonth = month + 1;
          showDate = showDate - lastDate;
        }
        if (thisMonth === 0) thisMonth = 12;
        if (thisMonth === 13) thisMonth = 1;

        ret.push({
          month: thisMonth, // 月份
          date: date, // 真实的日期;
          showDate: showDate, // 显示的日期;
          allDate:
            year +
            "-" +
            (thisMonth < 10 ? "0" + thisMonth : thisMonth) +
            "-" +
            (showDate < 10 ? "0" + showDate : showDate),
        });
      }
      return ret;
    },
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-preview.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/lvgl-maker-preview.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  methods: {
    async doPreviewLvgl() {
      await Ti.App.Open({
        title: "LuatOS终端模拟器",
        position: "center",
        width: "96%",
        height: "96%",
        textOk: null,
        textCancel: 'i18n:close',
        comType: "LvglSimulator",
        comConf: {
          deviceWidth: this.myDataDevice.width,
          deviceHeight: this.myDataDevice.height
        }
      })
    }
  }
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'wb-mcu.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/workbench/com/wb-mcu/wb-mcu.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props : {
    
  },
  //////////////////////////////////////////
  computed : {
    //--------------------------------------
    TopClass() {
      return this.getTopClass()
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods : {
    //--------------------------------------
    //--------------------------------------
  }
  //////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'workbench-computed.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/workbench/workbench-computed.mjs'] = (function(){
const __TI_MOD_EXPORT_VAR_NM = {
  //---------------------------------------------------
  TheLayout() {
    return {
      type: "cols",
      border: true,
      keepCustomizedTo: "Minke-Workbench-Layout-Main-Col",
      blocks: [
        /*{
          type: "rows",
          border: true,
          size: "15%",
          blocks: [
            {
              icon: "fas-sitemap",
              title: "源文件",
              name: "tree",
              body: "tree",
              size: "70%",
            },
            {
              icon: "fab-codepen",
              title: "系统模块",
              name: "global",
              body: "global",
            },
          ],
        },*/
        {
          icon: "fas-sitemap",
          title: "源文件",
          name: "tree",
          body: "tree",
          size: "15%",
          minSize: 50,
        },
        {
          name: "arena",
          body: "arena",
        },
      ],
    };
  },
  //---------------------------------------------------
  TheSchema() {
    return {
      tree: {
        comType: "WorkbenchSourceTree",
        comConf: {
          data: this.projectFiles,
          currentId: this.currentFileId,
        },
      },
      global: {
        comType: "WorkbenchImports",
      },
      arena: {
        comType: "WorkbenchArena",
        comConf: {
          meta: this.currentFile,
          content: this.currentFileContent,
          list: this.list,
          currentId: this.currentId,
          checkedIds: this.checkedIds,
          projectId: this.CurrentProjectId,
        },
      },
      mcu: {
        comType: "WorkbenchMcu",
      },
      devices: {
        comType: "WorkbenchDevices",
      },
    };
  },
  //---------------------------------------------------
};
return __TI_MOD_EXPORT_VAR_NM;;
})()
// ============================================================
// EXPORT 'workbench-global-imports.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/workbench/workbench-global-imports.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////////////
  props : {
    
  },
  ///////////////////////////////////////////////////////
  computed : {
    //---------------------------------------------------
    //---------------------------------------------------
  },
  ///////////////////////////////////////////////////////
  methods : {
    //---------------------------------------------------
    //---------------------------------------------------
  }
  ///////////////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-gauge.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/gauge/lvgl-gauge.mjs'] = (function(){
const calcCircumference = (r) => {
  return Math.PI * r * 2;
};

const _M = {
  ///////////////////////////////////////////////
  props: {
    needles: {
      type: Array,
      default() {
        return [];
      },
    },
    scale: {
      type: Array,
      default() {
        return [220, 21, 6];
      },
    },
    criticalValue: {
      type: Number,
      default: 80,
    },
    angleOffset: {
      type: Number,
      default: 0,
    },
    range: {
      type: Array,
      default() {
        return [0, 100];
      },
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    heightReal: 0,
    widthReal: 0,
    zoomScale: {
      type: Number,
      default: 1,
    },
  },
  data() {
    return {
      centerR: 5,
      centerX: 50,
      centerY: 50,
      criR: 45,
      criX: 50,
      criY: 50,
    };
  },
  ///////////////////////////////////////////////
  computed: {
    CurrMainStyle() {
      return _.get(this.defaultStatus, "mainPart") || {};
    },
    CurrMajorStyle() {
      return _.get(this.defaultStatus, "majorPart") || {};
    },
    CurrNeedleStyle() {
      return _.get(this.defaultStatus, "needlePart") || {};
    },
    guageBgStyle() {
      let css = {};
      let bgStyle = this.setCssBackgroundStyle(
        css,
        this.CurrMainStyle.bg || {}
      );
      if (this.angleOffset > 0) {
        css.transform = `rotate(${this.angleOffset}deg)`;
      }
      return css;
    },
    bgStyle() {
      let scale = (this.width / 100) * this.zoomScale;
      let css = {
        transform: `scale(${scale})`,
        transformOrigin: "0 0",
      };
      return css;
    },
    centerStyle() {
      return {
        fill: "#333",
      };
    },
    meterInfo() {
      let dftDeg = 90;
      let drawDeg = this.scale[0];
      let blankDeg = 360 - drawDeg;
      let startDeg = dftDeg + blankDeg / 2;
      let normalColor = "#888888";
      let criticalColor = "#01a2b1";
      // 分割角度
      let markDeg = drawDeg / (this.scale[1] - 1);
      let labelDeg = drawDeg / (this.scale[2] - 1);
      return {
        dftDeg,
        drawDeg,
        blankDeg,
        startDeg,
        markDeg,
        labelDeg,
        normalColor,
        criticalColor,
      };
    },
    meterMarks() {
      let mi = this.meterInfo;
      let arr = [];
      let sVal = this.range[0];
      let eVal = this.range[1];
      let spVal = (eVal - sVal) / (this.scale[1] - 1);
      for (let i = 0; i < this.scale[1]; i++) {
        let rotate = mi.startDeg + mi.markDeg * i;
        let currVal = sVal + spVal * i;
        let sColor =
          currVal >= this.criticalValue ? mi.criticalColor : mi.normalColor;
        arr.push({
          stroke: sColor,
          strokeWidth: 1.2,
          transformOrigin: "50px 50px",
          transform: `rotate(${rotate}deg)`,
        });
      }
      // console.log("marks:\n" + JSON.stringify(arr, null, 2));
      return arr;
    },
    meterLabelMarks() {
      let mi = this.meterInfo;
      let arr = [];
      let sVal = this.range[0];
      let eVal = this.range[1];
      let spVal = (eVal - sVal) / (this.scale[2] - 1);
      for (let i = 0; i < this.scale[2]; i++) {
        let rotate = mi.startDeg + mi.labelDeg * i;
        let currVal = sVal + spVal * i;
        let sColor =
          currVal >= this.criticalValue ? mi.criticalColor : mi.normalColor;
        arr.push({
          stroke: sColor,
          strokeWidth: 3,
          transformOrigin: "50px 50px",
          transform: `rotate(${rotate}deg)`,
        });
      }
      // console.log("marks:\n" + JSON.stringify(arr, null, 2));
      return arr;
    },
    meterLabels() {
      let mi = this.meterInfo;
      let arr = [];
      let sVal = this.range[0];
      let eVal = this.range[1];
      let spVal = (eVal - sVal) / (this.scale[2] - 1);
      for (let i = 0; i < this.scale[2]; i++) {
        let rotate = mi.startDeg + mi.labelDeg * i;
        arr.push({
          text: sVal + spVal * i,
          style: {
            color: "#333",
            fontSize: "6px",
            transformOrigin: "50px 50px",
            transform: `rotate(${rotate}deg)`,
          },
        });
      }
      // console.log("marks:\n" + JSON.stringify(arr, null, 2));
      return arr;
    },
    meterCritical() {
      let mi = this.meterInfo;
      let maxC = calcCircumference(this.criR);
      let sVal = this.range[0];
      let eVal = this.range[1];
      let criVal = this.criticalValue;
      let perDfs = 1 - criVal / (eVal - sVal);
      let dashOffset = maxC - maxC * ((mi.drawDeg * perDfs) / 360);
      let rotate = mi.startDeg + mi.drawDeg * (1 - perDfs);
      let css = {
        strokeDasharray: maxC,
        strokeDashoffset: dashOffset,
        stroke: mi.criticalColor,
        strokeWidth: 2.5,
        transform: `rotate(${rotate}deg)`,
        transformOrigin: "50px 50px",
      };
      return css;
    },
  },
  ///////////////////////////////////////////////
  methods: {
    getNeedleStyle(idx, needle) {
      // 默认旋转 90
      let mi = this.meterInfo;
      let range = this.range[1] - this.range[0];
      let needleDeg = mi.startDeg + (needle.value / range) * mi.drawDeg;
      let strokeWidth = (this.CurrNeedleStyle.line || {}).width || 2;
      // console.log(`${idx}. deg:${needleDeg}`);
      let css = {
        stroke: needle.color,
        strokeWidth,
        transformOrigin: "50px 50px",
        transform: `rotate(${needleDeg}deg)`,
      };
      return css;
    },
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-menu.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/lvgl-maker-menu.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    hasCopiedBlock() {
      return this.myCopiedBlock &&
        this.myCopiedBlock.comType &&
        this.myCopiedBlock.comConf
        ? true
        : false;
    },
    //--------------------------------------
    MenuItems() {
      return [
        {
          icon: "zmdi-plus",
          text: "添加组件",
          disabled: {
            "!hasCurrentScreen": true,
          },
          action: this.OnAddLvglCom,
        },
        {
          type: "line",
        },
        {
          icon: "zmdi-delete",
          tip: "删除当前组件",
          disabled: {
            "!hasCurrentBlock": true,
          },
          action: this.OnRemoveLvglCom,
        },
        {
          type: "line",
        },
        {
          icon: "zmdi-copy",
          text: "复制",
          disabled: {
            "!hasCurrentBlock": true,
          },
          action: this.OnCopyLvglCom,
        },
        {
          icon: "zmdi-paste",
          text: "粘贴",
          enabled: {
            hasCopiedBlock: true,
          },
          action: this.OnPasteLvglCom,
        },
        {
          type: "line",
        },
        {
          type: "Group",
          icon: "im-menu-list",
          items: [
            {
              icon: "fas-long-arrow-alt-right",
              text: "转移当前组件到屏幕...",
              disabled: {
                "!hasCurrentBlock": true,
              },
              action: this.OnTransCurrentLvglScreenCom,
            },
            {
              type: "line",
            },
            {
              type: "Group",
              text: "控件显示",
              items: [
                {
                  name: "showBlockOutline",
                  type: "action",
                  text: "轮廓线",
                  altDisplay: {
                    icon: "fas-check",
                    capture: false,
                  },
                  action: this.OnToggleShowBlockOutline,
                },
                {
                  name: "showIndicateIcon",
                  type: "action",
                  text: "指示图标",
                  altDisplay: {
                    icon: "fas-check",
                    capture: false,
                  },
                  action: this.OnToggleShowIndicateIcon,
                },
                {
                  name: "showBlockType",
                  type: "action",
                  text: "类型提示",
                  altDisplay: {
                    icon: "fas-check",
                    capture: false,
                  },
                  action: this.OnToggleShowBlockType,
                },
                {
                  name: "showBlockName",
                  type: "action",
                  text: "控件名称",
                  altDisplay: {
                    icon: "fas-check",
                    capture: false,
                  },
                  action: this.OnToggleShowBlockName,
                },
              ],
            },
            {
              type: "line",
            },
            {
              icon: "zmdi-tablet-android",
              text: "添加屏幕",
              action: this.OnAddLvglScreen,
            },
            // {
            //   name: "showScreenRotation",
            //   type: "action",
            //   text: "显示屏幕旋转方向",
            //   altDisplay: {
            //     icon: "fas-check",
            //     capture: false,
            //   },
            //   action: this.OnToggleShowScreenRotation,
            // },
            {
              type: "line",
            },
            {
              icon: "fas-exchange-alt",
              text: "转移全部组件到屏幕...",
              disabled: {
                "!hasCurrentScreen": true,
              },
              action: this.OnTransLvglScreenComs,
            },
            {
              icon: "im-x-mark",
              text: "移除当前屏幕",
              disabled: {
                "!hasCurrentScreen": true,
              },
              action: this.OnRemoveLvglScreen,
            },
            {
              type: "line",
            },
            {
              icon: "im-code",
              text: "查看源代码",
              action: this.OnViewSourceCode,
            },
            {
              type: "line",
            },
            {
              icon: "font-awesome",
              text: "设计器更新记录",
              action: this.OnViewChangeLog,
            },
          ],
        },
      ];
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    async OnAddLvglCom() {
      let reo = await Ti.App.Open({
        title: "选择组件",
        width: "5rem",
        height: "100%",
        position: "left",
        result: undefined,
        model: { event: "select" },
        comType: "TiWall",
        comConf: {
          idBy: "value",
          data: this.LvglComList,
          display: {
            key: "..",
            comType: "TiObjThumb",
            comConf: {
              id: ":=item.value",
              title: ":=item.text",
              preview: {
                type: "font",
                value: ":=item.icon",
              },
            },
          },
        },
        components: ["@com:ti/wall", "@com:ti/obj/thumb"],
      });

      // 用户取消
      if (!reo || !reo.currentId) {
        return;
      }

      let com = _.get(this.LvglComDict, reo.currentId);
      // Guard
      if (!com) {
        return;
      }

      // Load comSetup
      let comType = com.value;
      let setup = await this.loadComSetup(comType);
      this.myCurrentBlockForceRatio = setup.forceRatio;

      let block = {
        ..._.assign({}, setup.measure),
        defaultResizable: setup.defaultResizable,
        comType,
        comConf: _.assign({}, setup.comConf),
      };

      // Add com to stage
      this.addBlockToScreen(block);
    },
    //--------------------------------------
    OnRemoveLvglCom() {
      // Guard
      if (!this.myCurrentBlockName || !this.hasCurrentScreen) {
        return;
      }

      // Revmove block from stage
      this.removeBlockFromScreen(this.myCurrentBlockName);
    },
    //--------------------------------------
    OnCopyLvglCom() {
      // 防守
      if (!this.myCurrentBlockName) {
        return;
      }
      let screen = this.myDataScreens[this.myCurrentScreenIndex] || {};
      let block = _.find(
        screen.layout.blocks,
        ({ name }) => name == this.myCurrentBlockName
      );
      if (!block) {
        return;
      }
      let com = _.get(this.myDataSchema, block.body);
      if (!com) {
        return;
      }

      this.myPastedCount = 0;
      this.myCopiedBlock = _.assign(_.cloneDeep(com), {
        ...block,
      });
      // Maybe need to view the source code
      Ti.Be.writeToClipboard(JSON.stringify(this.myCopiedBlock, null, "   "));

      // Blink it in stage
      let $stage = this.findComBy(($com) => {
        return $com.tiComType == "LvglMakerStage";
      });
      $stage.blinkBlock(this.myCurrentBlockName);
    },
    //--------------------------------------
    OnPasteLvglCom() {
      // 防守
      if (!this.hasCopiedBlock) {
        return;
      }
      let block = _.cloneDeep(this.myCopiedBlock);
      // Offset measue to show
      let n = this.myPastedCount + 1;
      block.x += 10 * n;
      block.y += 10 * n;
      this.addBlockToScreen(block);
      this.myPastedCount++;
    },
    //--------------------------------------
    async OnViewSourceCode() {
      let sourcecode = JSON.stringify(this.ContentData, null, "   ");
      let newContent = await Ti.App.Open({
        title: "查看源代码",
        //------------------------------------------
        width: "80%",
        height: "90%",
        position: "top",
        result: sourcecode,
        //------------------------------------------
        comType: "ti-text-raw",
        comConf: {
          readonly: false,
          placeholder: "JSON 源代码",
          showTitle: false,
          ignoreKeyUp: true,
        },
        //------------------------------------------
        components: ["@com:ti/text/raw"],
        //------------------------------------------
      });

      // 用户取消
      if (!newContent) {
        return;
      }

      // 解析看看是否是合法的 JSON
      try {
        let lvgl = JSON.parse(newContent);
        this.notifyChange(lvgl);
      } catch (E) {
        return await Ti.Alert("JSON 字符串非法！！！");
      }
    },
    async OnViewChangeLog() {
      let logPath = `@Site:com/lvgl/change-log.json`;
      let logJson = await Ti.Load(logPath);
      let changeLog = "";
      for (let i = 0; i < logJson.history.length; i++) {
        const history = logJson.history[i];
        changeLog += "# " + history.date;
        changeLog += "\n\n";
        for (let j = 0; j < history.content.length; j++) {
          let no = j + 1;
          if (no < 10) {
            no = " " + no;
          }
          const cline = history.content[j];
          changeLog += no + ". " + cline;
          changeLog += "\n";
        }
        changeLog += "\n";
      }
      let newContent = await Ti.App.Open({
        title: "设计器更新记录",
        //------------------------------------------
        width: "80%",
        height: "90%",
        position: "top",
        result: changeLog,
        //------------------------------------------
        comType: "ti-text-raw",
        comConf: {
          readonly: true,
          placeholder: "无内容",
          showTitle: false,
          ignoreKeyUp: true,
        },
        //------------------------------------------
        components: ["@com:ti/text/raw"],
        //------------------------------------------
      });

      // 用户取消
      if (!newContent) {
        return;
      }
    },
    //--------------------------------------
    async OnAddLvglScreen() {
      let screenName = await Ti.Prompt(
        "请输入新的屏幕名称（英文数字或者下划线的组合）"
      );
      screenName = _.trim(screenName);
      // User cancel
      if (!screenName) {
        return;
      }
      // 记入屏幕
      this.addNewScreen(screenName);
    },
    //--------------------------------------
    async OnRemoveLvglScreen() {
      if (!this.hasCurrentScreen) {
        return;
      }
      let msg = `您想删除当前屏幕【${this.CurrentScreen.name}】，并移除其内的全部组件吗`;
      if (await Ti.Confirm(msg)) {
        this.removeScreen(this.myCurrentScreenIndex);
      }
    },
    //--------------------------------------
    async selectTargetScreen() {
      if (!this.hasCurrentScreen) {
        return {};
      }
      // Get candidate screen Names
      let canScreens = [];
      _.forEach(this.myDataScreens, (screen, index) => {
        if (index != this.myCurrentScreenIndex) {
          canScreens.push({
            icon: "zmdi-tablet-android",
            text: screen.name,
            value: index,
          });
        }
      });
      if (_.isEmpty(canScreens)) {
        await Ti.Toast.Open("抱歉，您只有一个屏幕！", "warn");
        return {};
      }
      // Get target screen
      let targetIndex = await Ti.App.Open({
        title: "选择目标屏幕",
        width: 400,
        height: "60%",
        position: "top",
        comType: "TiBulletRadio",
        comConf: {
          options: canScreens,
          autoI18n: false,
        },
        components: ["@com:ti/bullet/radio"],
      });

      // Find target
      let taScreen = _.nth(this.myDataScreens, targetIndex);
      if (!taScreen) {
        return {};
      }
      return {
        index: targetIndex,
        screen: taScreen,
      };
    },
    //--------------------------------------
    async OnTransCurrentLvglScreenCom() {
      if (!this.CurrentBlock) {
        return;
      }
      let { screen } = await this.selectTargetScreen();
      if (!screen) {
        return;
      }
      let theBlock = _.cloneDeep(this.CurrentBlock);
      let blocks = _.cloneDeep(this.CurrentScreen.layout.blocks);
      this.CurrentScreen.layout.blocks = _.filter(blocks, ({ name }) => {
        return name != theBlock.name;
      });
      screen.layout.blocks.push(theBlock);

      let lvgl = this.getLvglData();
      this.notifyChange(lvgl);
    },
    //--------------------------------------
    async OnTransLvglScreenComs() {
      let { screen } = await this.selectTargetScreen();
      if (!screen) {
        return;
      }

      // Trans screen blocks
      let blocks = _.cloneDeep(this.CurrentScreen.layout.blocks);
      this.CurrentScreen.layout.blocks = [];
      screen.layout.blocks.push(...blocks);

      let lvgl = this.getLvglData();
      this.notifyChange(lvgl);
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-chart.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/chart/lvgl-chart.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    series: {
      type: Array,
      default() {
        return [];
      },
    },
    type: {
      type: String,
      default: "CHART_TYPE_LINE",
    },
    pointCount: {
      type: Number,
      default: 10,
    },
    yRange: {
      type: Array,
      default() {
        return [0, 100];
      },
    },
    divLineCount: {
      type: Array,
      default() {
        return [3, 5];
      },
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    xTick: {
      type: Object,
      default() {
        return {
          text: "",
          num: 1,
          major: 10,
          minor: 5,
          axis: "CHART_AXIS_INVERSE_LABELS_ORDER",
        };
      },
    },
    yTick: {
      type: Object,
      default() {
        return {
          text: "",
          num: 1,
          major: 10,
          minor: 5,
          axis: "CHART_AXIS_DRAW_LAST_TICK",
        };
      },
    },
    heightReal: {
      type: Number,
      default: 100,
    },
    widthReal: {
      type: Number,
      default: 100,
    },
    zoomScale: {
      type: Number,
      default: 1,
    },
    width: {
      type: Number,
      default: 100,
    },
    height: {
      type: Number,
      default: 100,
    },
  },
  data() {
    return {
      xStart: 0,
      yStart: 0,
      strokeWidth: 1,
    };
  },
  watch: {
    widthReal() {
      // console.log(
      //   "x-range: " +
      //     this.xSizeCalc +
      //     "(" +
      //     this.xStartCalc +
      //     ", " +
      //     this.xEndCalc +
      //     ")"
      // );
      // console.log(
      //   "y-range: " +
      //     this.ySizeCalc +
      //     "(" +
      //     this.yStartCalc +
      //     ", " +
      //     this.yEndCalc +
      //     ")"
      // );
    },
    zoomScale() {
      console.log("zoomScale:" + this.zoomScale);
      console.log("svg-style:" + JSON.stringify(this.svgStyle));
    },
  },
  computed: {
    xSize() {
      return this.widthReal;
    },
    xEnd() {
      return this.widthReal;
    },
    ySize() {
      return this.heightReal;
    },
    yEnd() {
      return this.heightReal;
    },
    viewPort() {
      return "0 0 " + this.widthReal + " " + this.heightReal;
    },
    currPadding() {
      return this.CurrBgStyle.pad || {};
    },
    currBorder() {
      return this.CurrBgStyle.border || {};
    },
    spaceTop() {
      let pt = this.currPadding.top || 0;
      let bt = this.currBorder.width || 0;
      return pt + bt;
    },
    spaceBottom() {
      let pt = this.currPadding.bottom || 0;
      let bt = this.currBorder.width || 0;
      return pt + bt;
    },
    spaceLeft() {
      let pt = this.currPadding.left || 0;
      let bt = this.currBorder.width || 0;
      return pt + bt;
    },
    spaceRight() {
      let pt = this.currPadding.right || 0;
      let bt = this.currBorder.width || 0;
      return pt + bt;
    },
    xStartCalc() {
      let xStart = this.xStart;
      xStart += this.spaceLeft;
      return xStart;
    },
    xEndCalc() {
      let xEnd = this.xEnd;
      xEnd -= this.spaceRight;
      return xEnd;
    },
    xSizeCalc() {
      let xSize = this.xSize;
      xSize -= this.spaceLeft;
      xSize -= this.spaceRight;
      return xSize;
    },
    yStartCalc() {
      let xStart = this.yStart;
      xStart += this.spaceTop;
      return xStart;
    },
    yEndCalc() {
      let xEnd = this.yEnd;
      xEnd -= this.spaceBottom;
      return xEnd;
    },
    ySizeCalc() {
      let ySize = this.ySize;
      ySize -= this.spaceTop;
      ySize -= this.spaceBottom;
      return ySize;
    },
    CurrBgStyle() {
      return _.get(this.defaultStatus, "bgPart") || {};
    },
    containerBgStyle() {
      let css = {};
      this.setCssBackgroundStyle(css, this.CurrBgStyle.bg);
      this.setCssBorder(css, this.CurrBgStyle.border);
      return css;
    },
    svgStyle() {
      let css = {};
      // if (this.xSize > 0 && this.ySize > 0) {
      //   let scaleX = this.zoomScale;
      //   let scaleY = this.zoomScale;
      //   css = {
      //     transform: `scale(${scaleX},${scaleY})`,
      //     transformOrigin: "0 0",
      //   };
      // }
      return css;
    },
    divisionLines() {
      let hdiv = this.divLineCount[0];
      let vdiv = this.divLineCount[1];
      let rsize = this.strokeWidth / 2;
      let hLines = [];
      let hsize = this.ySizeCalc / (hdiv + 1) - rsize;
      for (let i = 0; i < hdiv + 2; i++) {
        let x1 = this.xStartCalc - this.strokeWidth * 2;
        let x2 = this.xEndCalc - this.strokeWidth;
        let y1 = this.yStartCalc + hsize * i - (i > 0 ? this.strokeWidth : 0);
        let y2 = y1;
        hLines.push({
          x1,
          x2,
          y1,
          y2,
          style: {
            stroke: "#aaaaaa",
            strokeWidth: this.strokeWidth,
            strokeDasharray: "2,2",
          },
        });
      }

      let vLines = [];
      let vsize = this.xSizeCalc / (vdiv + 1) - rsize;
      for (let i = 0; i < vdiv + 2; i++) {
        let x1 = this.xStartCalc + vsize * i;
        let x2 = x1;
        let y1 = this.yStartCalc - this.strokeWidth * 2;
        let y2 = this.yEndCalc - this.strokeWidth;
        vLines.push({
          x1,
          x2,
          y1,
          y2,
          style: {
            stroke: "#aaaaaa",
            strokeWidth: this.strokeWidth,
            strokeDasharray: "2,2",
          },
        });
      }

      return {
        h: hLines,
        v: vLines,
      };
    },
    seriesDataLine() {
      if (
        this.type != "CHART_TYPE_LINE" ||
        this.xSize <= 0 ||
        this.ySize <= 0
      ) {
        return {
          dlines: [],
          dcircles: [],
        };
      }
      let series = this.series || [];
      let rsize = 0.05;
      let dlines = [];
      let dcircles = [];
      let ymin = this.yRange[0];
      let ymax = this.yRange[1];
      let yscale = ymax - ymin;
      for (let i = 0; i < series.length; i++) {
        const sdata = series[i];
        let points = sdata.points;
        let startPos = sdata.start || 0;
        let pxsize = this.xSizeCalc / (this.pointCount - 1) - rsize;
        let xys = [];
        for (let j = 0; j < points.length; j++) {
          let rpos = startPos + j;
          if (rpos > this.pointCount - 1) {
            continue;
          }
          let py = points[j];
          let pyVal =
            (1 - (py - ymin) / yscale) * this.ySizeCalc + this.yStartCalc;
          let pxVal = this.xStartCalc + pxsize * rpos;
          xys.push(`${pxVal},${pyVal}`);
          dcircles.push({
            x: pxVal,
            y: pyVal,
            r: 2,
            style: {
              fill: sdata.color,
            },
          });
        }
        dlines.push({
          points: xys.join(" "),
          style: {
            stroke: sdata.color,
            strokeWidth: this.strokeWidth,
            fill: "none",
          },
        });
      }
      return {
        dlines,
        dcircles,
      };
    },
    seriesDataColumn() {
      if (
        this.type != "CHART_TYPE_COLUMN" ||
        this.xSize <= 0 ||
        this.ySize <= 0
      ) {
        return {
          dcolumns: [],
        };
      }
      let series = this.series || [];
      let rsize = 0.05;
      let dcolumns = [];
      let ymin = this.yRange[0];
      let ymax = this.yRange[1];
      let yscale = ymax - ymin;
      let cw = 4;
      for (let i = 0; i < series.length; i++) {
        const sdata = series[i];
        let points = sdata.points;
        let startPos = sdata.start || 0;
        let pxsize = this.xSizeCalc / this.pointCount - rsize;
        for (let j = 0; j < points.length; j++) {
          let rpos = startPos + j;
          if (rpos > this.pointCount - 1) {
            continue;
          }
          let py = points[j];
          let pyVal =
            (1 - (py - ymin) / yscale) * this.ySizeCalc + this.yStartCalc;
          let pxVal = this.xStartCalc + pxsize * rpos + i * cw;
          dcolumns.push({
            x: pxVal,
            y: pyVal,
            width: cw,
            height: this.ySizeCalc - pyVal + this.yStartCalc,
            style: {
              fill: sdata.color,
            },
          });
        }
      }
      return {
        dcolumns,
      };
    },
    xTicks() {
      let texts = [];
      let marks = [];
      if (this.xSize > 0 && this.ySize > 0) {
        let lineSet = this.CurrBgStyle.line || {};
        let textSet = this.CurrBgStyle.text || {};
        let rsize = 0.05;
        let tickConf = this.xTick;
        let xtArr = tickConf.text.trim().split("\n");
        let axisSet = this.xTick.axis || "CHART_AXIS_DRAW_LAST_TICK";
        if (xtArr.length > 0) {
          if (axisSet == "CHART_AXIS_INVERSE_LABELS_ORDER") {
            xtArr.reverse();
          }
          let vsize =
            xtArr.length > 1
              ? this.xSizeCalc / (xtArr.length - 1) - rsize
              : this.xSizeCalc;
          for (let i = 0; i < xtArr.length; i++) {
            const t = xtArr[i];
            if (!t) {
              continue;
            }
            let tx = this.xStartCalc + vsize * i;
            let ty = this.yEndCalc + 10;

            // 文字
            texts.push({
              x: tx - (t.length * 2.5) / 2,
              y: ty,
              fontSize:
                textSet.font && textSet.font.size ? textSet.font.size / 5 : 3,
              content: t,
              style: {
                fill: textSet.color || "#333333",
              },
            });

            let msw = lineSet.width ? lineSet.width / 5 : 0.3;

            // 次要
            let minorsize = vsize / (tickConf.num || 1);
            if (tickConf.num && tickConf.num > 1 && i + 1 < xtArr.length) {
              for (let j = 1; j < tickConf.num; j++) {
                marks.push({
                  x1: tx - msw / 2 + minorsize * j,
                  y1: this.yEndCalc,
                  x2: tx - msw / 2 + minorsize * j,
                  y2: this.yEndCalc + (tickConf.minor || 5) / 2,
                  style: {
                    stroke: lineSet.color || "#333333",
                    strokeWidth: msw,
                    strokeOpacity: lineSet.opa ? lineSet.opa / 255 : 1,
                  },
                });
              }
            }

            // 主要
            if (
              axisSet == "CHART_AXIS_SKIP_LAST_TICK" &&
              i + 1 == xtArr.length
            ) {
              continue;
            }
            marks.push({
              x1: tx - msw / 2,
              y1: this.yEndCalc,
              x2: tx - msw / 2,
              y2: this.yEndCalc + (tickConf.major || 10) / 2,
              style: {
                stroke: lineSet.color || "#333333",
                strokeWidth: msw,
                strokeOpacity: lineSet.opa ? lineSet.opa / 255 : 1,
              },
            });
          }
        }
      }
      return {
        texts,
        marks,
      };
    },
    yTicks() {
      let texts = [];
      let marks = [];
      if (this.xSize > 0 && this.ySize > 0) {
        let lineSet = this.CurrBgStyle.line || {};
        let textSet = this.CurrBgStyle.text || {};
        let rsize = 0.1;
        let tickConf = this.yTick;
        let axisSet = this.yTick.axis || "CHART_AXIS_INVERSE_LABELS_ORDER";
        let xtArr = tickConf.text.trim().split("\n");
        if (xtArr.length > 0) {
          if (axisSet != "CHART_AXIS_INVERSE_LABELS_ORDER") {
            xtArr.reverse();
          }
          let vsize =
            xtArr.length > 1
              ? this.ySizeCalc / (xtArr.length - 1) - rsize
              : this.ySizeCalc;
          for (let i = 0; i < xtArr.length; i++) {
            const t = xtArr[i];
            let tx = this.xStartCalc - 10;
            let ty = this.yEndCalc - vsize * i;
            if (!t) {
              continue;
            }
            // 文字
            texts.push({
              x: tx,
              y: ty + (t.length * 2.5) / 2,
              fontSize:
                textSet.font && textSet.font.size ? textSet.font.size / 5 : 3,
              content: t,
              style: {
                fill: textSet.color || "#333333",
              },
            });

            let msh = lineSet.width ? lineSet.width / 5 : 0.3;
            // 次要
            let minorsize = vsize / (tickConf.num || 1);
            if (tickConf.num && tickConf.num > 1 && i + 1 < xtArr.length) {
              for (let j = 0; j < tickConf.num; j++) {
                marks.push({
                  x1: this.xStartCalc,
                  y1: ty - msh / 2 - minorsize * j,
                  x2: this.xStartCalc - (tickConf.minor || 5) / 2,
                  y2: ty - msh / 2 - minorsize * j,
                  style: {
                    stroke: lineSet.color || "#333333",
                    strokeWidth: msh,
                    strokeOpacity: lineSet.opa ? lineSet.opa / 255 : 1,
                  },
                });
              }
            }

            // 主要
            if (
              axisSet == "CHART_AXIS_SKIP_LAST_TICK" &&
              i + 1 == xtArr.length
            ) {
              continue;
            }
            marks.push({
              x1: this.xStartCalc,
              y1: ty - msh / 2,
              x2: this.xStartCalc - (tickConf.major || 10) / 2,
              y2: ty - msh / 2,
              style: {
                stroke: lineSet.color || "#333333",
                strokeWidth: msh,
                strokeOpacity: lineSet.opa ? lineSet.opa / 255 : 1,
              },
            });
          }
        }
      }
      return {
        texts,
        marks,
      };
    },
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-btnmatrix.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/btnmatrix/lvgl-btnmatrix.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    //-------------------------------------------
    //-------------------------------------------
    // Aspec
    //-------------------------------------------
    
  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------

    //-------------------------------------------
  }
  ///////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'wb-imports.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/workbench/com/wb-imports/wb-imports.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props : {
    
  },
  //////////////////////////////////////////
  computed : {
    //--------------------------------------
    
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods : {
    //--------------------------------------
    //--------------------------------------
  }
  //////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'workbench.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/workbench/workbench.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////////////
  props: {
    "project": {
      type: Object
    },
    "currentFile": {
      type: Object
    },
    "currentFileContent": {
      type: String
    },
    "list": {
      type: Array,
      default: () => []
    },
    "currentId": {
      type: String
    },
    "checkedIds": {
      type: [Array, Object]
    }
  },
  ///////////////////////////////////////////////////////
  computed: {
    //---------------------------------------------------
    hasProject() {
      return !_.isEmpty(this.project)
    },
    //---------------------------------------------------
    CurrentProject() {
      if (this.hasProject) {
        return this.project
      }
    },
    //---------------------------------------------------
    CurrentProjectId() {
      return _.get(this.CurrentProject, "id")
    }
    //---------------------------------------------------
  },
  ///////////////////////////////////////////////////////
  methods: {
    //---------------------------------------------------
    //---------------------------------------------------
  }
  ///////////////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-outline.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/outline/lvgl-maker-outline.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  inject: ["$maker"],
  //////////////////////////////////////////
  props: {},
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    IsBlockLeaf() {
      return (node) => {
        return !_.isArray(node.blocks)
      }
    },
    //--------------------------------------
    ActionItems() {
      return [
        {
          name: "moveToTop",
          icon: "zmdi-long-arrow-tab zmdi-hc-rotate-270",
          text: "置顶",
          action: () => {
            this.moveToTop();
          },
        },
        {},
        {
          name: "moveUp",
          icon: "zmdi-long-arrow-up",
          text: "上移",
          action: () => {
            this.moveUp();
          },
        },
        {
          name: "moveDown",
          icon: "zmdi-long-arrow-down",
          text: "下移",
          action: () => {
            this.moveDown();
          },
        },
        {},
        {
          name: "moveToBottom",
          icon: "zmdi-long-arrow-tab zmdi-hc-rotate-90",
          text: "置底",
          action: () => {
            this.moveToBottom();
          },
        },
        {},
        {
          name: "moveOut",
          icon: "zmdi-long-arrow-left",
          text: "移出",
          action: () => {
            this.moveOut();
          },
        },
        {
          name: "moveIn",
          icon: "zmdi-long-arrow-right",
          text: "移入",
          action: () => {
            this.moveIn();
          },
        },
      ];
    },
    //--------------------------------------
    LvglBlockDisplay() {
      return [
        {
          key: "visibility",
          transNil: true,
          transformer: (visibility) => {
            return ({
              "visible": "fas-eye",
              "hidden": "fas-eye-slash",
            })[visibility] || "fas-eye"
          },
          comType: "TiIcon",
          comConf: {
            className: "icon-w36",
            notifyName: "toggle:block:visibility",
            notifyConf: {
              blockName: "=item.name"
            },
            stopPropagation: true
          }
        },
        {
          key: "comType",
          transformer: (lvglType) => {
            let com = this.LvglComDict[lvglType];
            return com.icon;
          },
          comType: "TiIcon",
        },
        "name",
        {
          key: "comType",
          transformer: (lvglType) => {
            let com = this.LvglComDict[lvglType];
            return com.text;
          },
          comConf: {
            className: "flex-none as-tip-block align-right",
          },
        },
      ];
    },
    //--------------------------------------
    LvglBlockOutlineTree() {
      let lvglSchema = this.schema
      const tidyBlocks = function (inputBlocks = []) {
        let list = [];
        _.forEach(inputBlocks, ({ name, body, blocks, visibility }, index) => {
          let com = _.get(lvglSchema, body) || {};
          let it = {
            name,
            index,
            comType: com.comType,
            visibility
          }
          if (!_.isEmpty(blocks)) {
            it.blocks = tidyBlocks(blocks)
          }
          list.unshift(it);
        });
        return list;
      }
      let blocks = _.get(this.LvglCurrentScreen, "layout.blocks");
      let list = tidyBlocks(blocks);
      return list;
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    OnSelectBlock({ currentId, checkedIds }) {
      console.log("Outline:select", { currentId, checkedIds })
      this.$notify("select:block", {
        name: currentId,
        checkedNames: Ti.Util.truthyKeys(checkedIds)
      });
    },
    //--------------------------------------
    moveToTop() {
      this.$maker.moveCurrentBlockTo("tail");
    },
    //--------------------------------------
    moveToBottom() {
      this.$maker.moveCurrentBlockTo("head");
    },
    //--------------------------------------
    moveUp() {
      this.$maker.moveCurrentBlockTo("next");
    },
    //--------------------------------------
    moveDown() {
      this.$maker.moveCurrentBlockTo("prev");
    },
    //--------------------------------------
    moveOut() {
      this.$maker.moveCurrentBlockTo("outside");
    },
    //--------------------------------------
    moveIn() {
      this.$maker.moveCurrentBlockTo("inside");
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-com-support.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/support/lvgl-com-support.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  inject: ["$maker", "$stage"],
  //////////////////////////////////////////
  props: {
    blockName: {
      type: String,
    },
    width: {
      type: Number,
      default: 0,
    },
    height: {
      type: Number,
      default: 0,
    },
  },
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    TopClass() {
      return this.getTopClass();
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    toCamelCase(text) {
      var textList = text.split("");
      for (let i = 0; i < textList.length; i++) {
        if (textList[i] == "-") {
          //寻找'-'分隔符
          textList.splice(i, 1); //删除这个分隔符，如果找到 就删除它
          textList[i] = textList[i].toUpperCase(); //删除 - 分隔符以后 后面的元素 前移  则直接修改为大写
        }
      }
      var str = textList.join(); //用join方法把 数组 转成 字符串
      var strHump = str.replace(/,/g, ""); //利用正则表达式查找所有的 , 并且修改为空字符串
      return strHump; //返回驼峰命名字符串
    },
    //--------------------------------------
    getLabelHtml(text = "", recolor = false, newline = false) {
      // 上色
      if (recolor) {
        let exp = /#[\w]{1,}\s{1}[^#]{1,}#/g;
        let marr = text.match(exp);
        if (marr && marr.length > 0) {
          // 替换原始文本
          for (let i = 0; i < marr.length; i++) {
            const mstr = marr[i];
            let mtext = mstr.match(/#([\w]{1,})\s{1}([^#]{1,})#/);
            let color = mtext[1];
            let cotent = mtext[2];
            let cssColor = Ti.Types.toColor(color).toString();
            let rehtml = `<span style="color: ${cssColor}">${cotent}</span>`;
            text = text.replace(mstr, rehtml);
          }
        }
      }
      // 添加换行
      if (newline) {
        let marr = text.split("\n");
        if (marr.length > 1) {
          text = marr.join("<br>");
        }
      }

      return text;
    }
  },
  //////////////////////////////////////////
  watch: {
    "blockName": {
      handler: function (newVal) {
        if (newVal) {
          this.$maker.signupCom(newVal, this)
        }
      },
      immediate: true
    }
  }
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'm-my-workbench.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['mod/workbench/m-my-workbench.mjs'] = (function(){
//////////////////////////////////////////////
function findIn(list = [], id) {
  if (!id) {
    return null
  }
  return _.find(list, li => li.id == id)
}
//////////////////////////////////////////////
const _M = {
  ////////////////////////////////////////////
  mutations: {
    //----------------------------------------
    //
    // Projects and files
    //
    //----------------------------------------
    setMyProjects(state, projList = []) {
      state.myProjects = projList
      state.currentProject = findIn(state.myProjects, state.currentProjId)
    },
    //----------------------------------------
    setCurrentProjId(state, projId) {
      state.currentProjId = projId
      state.currentProject = findIn(state.myProjects, state.currentProjId)
      // 记录到本地
      Ti.Storage.local.set("minke-wb-current-proj", projId)
    },
    //----------------------------------------
    setCurrentProjectFiles(state, files = []) {
      state.currentProjectFiles = files
      state.currentFile = findIn(state.currentProjectFiles, state.currentFileId)
    },
    //----------------------------------------
    updateProjectFileItem(state, fileItem) {
      if (!fileItem || !fileItem.id)
        return

      let list = _.map(state.currentProjectFiles, f => {
        if (f.id == fileItem.id) {
          return fileItem
        }
        return f
      })
      state.currentProjectFiles = list
      state.currentFile = findIn(state.currentProjectFiles, state.currentFileId)
    },
    //----------------------------------------
    setCurrentFileId(state, fileId) {
      state.currentFileId = fileId
      state.currentFile = findIn(state.currentProjectFiles, state.currentFileId)
    },
    //----------------------------------------
    //
    // Current File content
    //
    //----------------------------------------
    setCurrentFileContent(state, content) {
      let meta = state.currentFile;
      //console.log("setContent", content)
      // Guard
      if (!meta || _.isUndefined(content)) {
        state.currentFileContent = undefined
        state.__saved_currentFileContent = undefined
        state.status.changed = false
        return
      }
      //......................................
      // DIR
      if ("DIR" == meta.race) {
        state.currentFileContent = null
        state.__saved_currentFileContent = null
      }
      //......................................
      // File
      else if ("FILE" == meta.race) {
        //....................................
        // String content
        if (_.isString(content)) {
          state.currentFileContent = content
        }
        //....................................
        // null value
        else if (Ti.Util.isNil(content)) {
          state.currentFileContent = ""
        }
        //....................................
        // Take content as plain object or Array
        else {
          state.currentFileContent = JSON.stringify(content, null, '  ')
        }
        //....................................
      }
    },
    //----------------------------------------
    setCurrentFileSavedContent(state, content) {
      state.__saved_currentFileContent = content
    },
    //----------------------------------------
    //
    // Current Dir list
    //
    //----------------------------------------
    setList(state, list) {
      state.list = list
    },
    //----------------------------------------
    prependListItem(state, newItem) {
      Ti.Util.UpsertStateDataItemAt(state, newItem, -1, "..")
    },
    //----------------------------------------
    appendListItem(state, newItem) {
      Ti.Util.UpsertStateDataItemAt(state, newItem, 1, "..")
    },
    //----------------------------------------
    setListItem(state, newItem) {
      Ti.Util.UpsertStateDataItemAt(state, newItem, 0, "..")
      if (newItem && newItem.id == state.currentId) {
        state.meta = newItem
      }
    },
    //----------------------------------------
    mergeListItem(state, theItem) {
      Ti.Util.MergeStateDataItem(state, theItem, "..")
    },
    //----------------------------------------
    removeListItems(state, items = []) {
      Ti.Util.RemoveStateDataItems(state, items, "..")
    },
    //----------------------------------------
    setCurrentId(state, currentId) {
      state.currentId = currentId
    },
    //----------------------------------------
    setCheckedIds(state, checkedIds) {
      let ids
      if (_.isArray(checkedIds)) {
        ids = {}
        let c2 = _.filter(checkedIds, v => v)
        _.forEach(c2, v => ids[v] = true)
      } else {
        ids = _.pickBy(checkedIds, v => v)
      }
      state.checkedIds = ids
    },
    //----------------------------------------
    //
    // Status
    //
    //----------------------------------------
    setStatus(state, status) {
      state.status = _.assign({}, state.status, status)
    },
    //----------------------------------------
    syncStatusChanged(state) {
      if (Ti.Util.isNil(state.currentFileContent)
        && Ti.Util.isNil(state.__saved_currentFileContent)) {
        state.status.changed = false
      } else {
        state.status.changed = !_.isEqual(
          state.currentFileContent, state.__saved_currentFileContent)
      }
    }
    //----------------------------------------
  }
  ////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'buildshop.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/buildshop/buildshop.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////////////
  props: {
    "buildFonts": {
      type: Array,
      default: () => []
    },
    "buildMetas": {
      type: Array,
      default: () => []
    },
    "myBuildList": {
      type: Array,
      default: () => []
    },
    "currentBuildId": {
      type: String
    },
    "currentBuild": {
      type: Object
    },
    "currentBuildConf": {
      type: String
    },
    "currentBuildDataFile": {
      type: Object
    },
    "currentBuildDest": {
      type: Object
    },
    "currentBuildLog": {
      type: Object
    },
    "currentBuildSize": {
      type: Number,
      default: 0
    },
    "currentMaxBuildSize": {
      type: Number,
      default: 0
    },
    "status": {
      type: Object
    }
  },
  ///////////////////////////////////////////////////////
  computed: {
    //---------------------------------------------------
    hasCurrentBuild() {
      return this.currentBuild ? true : false
    },
    //---------------------------------------------------
    isLoading() {
      return _.get(this.status, "reloading")
    },
    //---------------------------------------------------
    TheLayout() {
      if (!this.hasCurrentBuild) {
        let rbConf;
        if (this.isLoading) {
          rbConf = {
            icon: "fab-docker",
            text: "加载中..."
          }
        } else {
          rbConf = {
            className: "is-info",
            icon: "fab-docker",
            text: "请创建您的第一个构建"
          }
        }
        return {
          type: "rows",
          blocks: [
            {
              body: {
                comType: "TiRoadblock",
                comConf: rbConf
              }
            }
          ]
        }
      }
      return {
        type: "cols",
        border: true,
        keepCustomizedTo: "Minke-BuildShop-Layout-Main-Col",
        blocks: [
          {
            name: "editconf",
            size: "62%",
            body: "editconf"
          },
          {
            name: "result",
            body: "result"
          }
        ]
      }
    },
    //---------------------------------------------------
    TheSchema() {
      if (!this.hasCurrentBuild) {
        return
      }
      return {
        editconf: {
          comType: "LuoBuildEditconf",
          comConf: {
            buildMetas: this.buildMetas,
            data: this.currentBuildConf,
            dataFile: this.currentBuildDataFile,
            currentBuild: this.currentBuild,
            status: this.status
          }
        },
        result: {
          comType: "LuoBuildResult",
          comConf: {
            data: this.currentBuildDest,
            buildLog: this.currentBuildLog,
            currentBuild: this.currentBuild,
            currentBuildSize: this.currentBuildSize,
            currentMaxBuildSize: this.currentMaxBuildSize,
            status: this.status
          }
        }
      }
    }
    //---------------------------------------------------
  },
  ///////////////////////////////////////////////////////
  methods: {
    //---------------------------------------------------
    //---------------------------------------------------
  }
  ///////////////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-imgbtn.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/imgbtn/lvgl-imgbtn.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  data: () => ({
    myImgSrc: undefined,
    naturalWidth: undefined,
    naturalHeight: undefined,
    imgLoading: false,
    myPreloadSrcList: [],
  }),
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    apiBase: {
      type: String,
    },
    projectId: {
      type: String,
    },
    status: {
      type: String,
      default: "DEFAULT",
    },
    src: {
      type: Object,
      default: undefined,
    },
    //-------------------------------------------
    // Aspec
    //-------------------------------------------
    transition: {
      type: Object,
      default: undefined,
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    releasedStatus: {
      type: Object,
      default: undefined,
    },
    pressedStatus: {
      type: Object,
      default: undefined,
    },
    checkedReleasedStatus: {
      type: Object,
      default: undefined,
    },
    checkedPressedStatus: {
      type: Object,
      default: undefined,
    },
    disabledStatus: {
      type: Object,
      default: undefined,
    },
    checkedDisabledStatus: {
      type: Object,
      default: undefined,
    },
  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    TopClass() {
      return this.getTopClass({
        "not-set": this.myImgSrc ? false : true,
      });
    },
    //-------------------------------------------
    CurrentStatus() {
      return _.camelCase(`${this.status}`);
    },
    //-------------------------------------------
    CurrentStyle() {
      let name = _.camelCase(`${this.status}_STATUS`);
      return (this[name] || {}).mainPart || {};
    },
    //-------------------------------------------
    CurrentSrc() {
      if (this.src) {
        let status = this.CurrentStatus;
        if (status == "default") {
          status = "released";
        }
        return this.src[status] || "";
      }
      return "";
    },
    //-------------------------------------------
    ImageStyle() {
      let bgStyle = this.getCssBackgroundStyle(this.CurrentStyle.bg || {});
      return bgStyle;
    },
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    // 图片加载完成，自动读取原始分辨率
    OnImageLoaded() {
      let $img = this.$refs.img;
      if ($img) {
        let w = $img.naturalWidth;
        let h = $img.naturalHeight;
        this.naturalWidth = w;
        this.naturalHeight = h;
        this.imgLoading = false;
        this.$notify("com:block:scale", {
          [this.blockName]: w / h,
        });
      }
    },
    //-------------------------------------------
    OnImagePreloaded({ index, orgSrc }) {
      // 如果已经设置了其他的 src，那么必然已经被调整了尺寸了
      // 这这个时候需要用开关说明一下，一遍 $maker.OnStageImagePreloaded 忽略
      // 图片尺寸的重置
      let hasOtherImgSrc = false
      _.forEach(this.src, (src) => {
        if (src && src != orgSrc) {
          hasOtherImgSrc = true
        }
      })

      // 通知一下图片真实的尺寸
      let $img = Ti.Dom.find(`img[data-index="${index}"]`, this.$refs.preloads);
      let width = $img.naturalWidth;
      let height = $img.naturalHeight;
      let preld = {
        src: orgSrc,
        keep_src: _.values(this.src),
        name: this.blockName,
        width,
        height,
        autoResizeOff: hasOtherImgSrc,
      };
      //console.log("OnImagePreloaded", preld)
      this.$notify("img:preloaded", preld);
    },
    //-------------------------------------------
    // 双击，自动恢复图片原始大小
    OnDblClickImage() {
      this.OnImageLoaded();
    },
    //-------------------------------------------
    async evalPreloadSrcList(src = {}) {
      let list = [];
      let keys = _.keys(src);
      for (let key of keys) {
        let orgSrc = src[key];
        if (!Ti.Util.isNil(orgSrc)) {
          list.push({
            index: list.length,
            key,
            orgSrc,
            imgSrc: await this.getImgSrc(orgSrc),
          });
        }
      }
      this.myPreloadSrcList = list;
    },
    //-------------------------------------------
    getImgSrc(src) {
      return new Promise((resolve) => {
        if (Ti.Util.isNil(src)) {
          resolve(null);
        }
        // 来自本地文件 (VSCode)
        else if (_.isFunction(window.vscodeEvalLocalImgSrc)) {
          window.vscodeEvalLocalImgSrc(src, (src2) => {
            resolve(src2);
          });
        }
        // 其他的认为来自本地
        else {
          resolve(
            [
              this.apiBase,
              "project/file/read",
              `?projId=${this.projectId}`,
              `&src=${src}`,
            ].join("")
          );
        }
      });
    },
    //-------------------------------------------
    async evalMyImgSrc(src) {
      // 重置
      if (!src) {
        this.myImgSrc = undefined;
        this.naturalHeight = undefined;
        this.naturalWidth = undefined;
        this.imgLoading = false;
        return;
      }
      //console.log("evalMyImgSrc", src);
      this.imgLoading = true;
      // 来自网络
      if (/^https?:\/\//.test(src)) {
        this.myImgSrc = src;
        return;
      }

      // 加载图片真实地址
      this.myImgSrc = await this.getImgSrc(src);
    },
    //-------------------------------------------
    isSrcInUsed(src) {
      let mySrcList = _.values(this.src)
      return _.indexOf(mySrcList, src) >= 0
    }
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  watch: {
    CurrentSrc: {
      handler: async function (newVal, oldVal) {
        if (!_.isEqual(newVal, oldVal)) {
          await this.evalMyImgSrc(newVal);
        }
      },
      immediate: true,
    },
    src: {
      handler: function (newVal, oldVal) {
        if (!_.isEqual(newVal, oldVal)) {
          this.evalPreloadSrcList(newVal);
        }
      },
      immediate: true,
    },
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-textarea.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/textarea/lvgl-textarea.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    //-------------------------------------------
    text: {
      type: String,
      default: "",
    },
    placeholderText: {
      type: String,
      default: "",
    },
    cursorHidden: {
      type: Boolean,
      default: false,
    },
    cursorBlinkTime: {
      type: Number,
      default: 20,
    },
    oneLine: {
      type: Boolean,
      default: true,
    },
    pwdMode: {
      type: Boolean,
      default: false,
    },
    acceptedChars: {
      type: String,
    },
    maxLength: {
      type: Number,
    },
    veryLongTexts: {
      type: Boolean,
      default: false,
    },
    scrollbarMode: {
      type: String,
      default: "MODE_OFF",
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    zoomScale: {
      type: Number,
      default: 1,
    },
  },
  ///////////////////////////////////////////////
  computed: {
    CurrBgStyle() {
      return _.get(this.defaultStatus, "bgPart") || {};
    },
    //-------------------------------------------
    textareaStyle() {
      let css = this.getCssBackgroundStyle(this.CurrBgStyle.bg || {});
      this.setCssText(css, this.CurrBgStyle.text, this.zoomScale);
      return css;
    },
    //-------------------------------------------
    TopStyle() {
      let css = {};
      return css;
    },
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-style-pad.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/style/pad/lvgl-maker-style-pad.mjs'] = (function(){
////////////////////////////////////////////////////////
const _M = {
  //////////////////////////////////////////////////////
  props: {
    //-----------------------------------
    // Data
    //-----------------------------------
    "value": {
      type: Object
    }
  },
  //////////////////////////////////////////////////////
  computed: {
    //--------------------------------------------------
    StyleForm() {
      return {
        spacing: "comfy",
        fields: [
          {
            "title": "上",
            "name": "top",
            "type": "Integer",
            "comType": "TiInputNum"
          },
          {
            "title": "下",
            "name": "bottom",
            "type": "Integer",
            "comType": "TiInputNum"
          },
          {
            "title": "左",
            "name": "left",
            "type": "Integer",
            "comType": "TiInputNum"
          },
          {
            "title": "右",
            "name": "right",
            "type": "Integer",
            "comType": "TiInputNum"
          },
          {
            "title": "内",
            "name": "inner",
            "type": "Integer",
            "comType": "TiInputNum"
          },
        ]
      }
    }
    //--------------------------------------------------
  }
  //////////////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-button.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/button/lvgl-button.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    //-------------------------------------------
    status: {
      type: String,
      default: "DEFAULT",
    },
    recolor: {
      type: Boolean,
      default: false,
    },
    //-------------------------------------------
    // Aspec
    //-------------------------------------------
    transition: {
      type: Object,
      default: undefined,
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    releasedStatus: {
      type: Object,
      default: undefined,
    },
    pressedStatus: {
      type: Object,
      default: undefined,
    },
    checkedReleasedStatus: {
      type: Object,
      default: undefined,
    },
    checkedPressedStatus: {
      type: Object,
      default: undefined,
    },
    disabledStatus: {
      type: Object,
      default: undefined,
    },
    checkedDisabledStatus: {
      type: Object,
      default: undefined,
    },
    text: {
      type: String,
      default: "",
    },
    zoomScale: {
      type: Number,
      default: 1,
    },
  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    CurrentStyle() {
      let name = _.camelCase(`${this.status}_STATUS`);
      return (this[name] || {}).mainPart || {};
    },
    //-------------------------------------------
    TopStyle() {
      let css = {};
      //.........................................

      //.........................................
      //.........................................
      return css;
    },
    //-------------------------------------------
    PartMainStyle() {
      let css = {
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        alignContent: "center",
        width: "100%",
        height: "100%",
      };
      //.........................................
      this.setCssNumberProp(
        css,
        "borderRadius",
        this.CurrentStyle.radius * this.zoomScale
      );
      //.........................................
      this.setCssBackgroundStyle(css, this.CurrentStyle.bg);
      this.setCssBorder(css, this.CurrentStyle.border);
      this.setCssShadow(css, this.CurrentStyle.shadow);
      this.setCssOutline(css, this.CurrentStyle.outline);
      this.setCssText(css, this.CurrentStyle.text, this.zoomScale);
      // Transition
      this.setCssTransition(css, this.transition);
      //.........................................
      return css;
    },
    //-------------------------------------------
    PartTextStyle() {
      let css = {
        width: "100%",
        position: "relative",
      };
      //.........................................
      let {
        color,
        opa,
        letterSpace,
        lineSpace,
        align = "CENTER",
        ofsX,
        ofsY,
        blendMode,
      } = this.CurrentStyle.value || {};
      //.........................................
      css.color = this.getCssColor(color, opa);
      this.setCssNumberProp(css, "letterSpacing", letterSpace);
      this.setCssNumberProp(css, "lineHeight", lineSpace);
      this.setCssNumberProp(css, "textAlign", _.toLower(align));
      this.setCssNumberProp(css, "left", ofsX);
      this.setCssNumberProp(css, "top", ofsY);
      this.setCssBlendMode(css, blendMode);
      //.........................................
      return css;
    },
    //-------------------------------------------
    ValueText() {
      return this.text;
    },
    ValueHtml() {
      return this.getLabelHtml(this.ValueText, this.recolor, true);
    },
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'minke-util.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['mod/minke-util.mjs'] = (function(){
const __TI_MOD_EXPORT_VAR_NM = {
  //---------------------------------------------------
  // [Any] => [{[$key]: Any}]
  arrayEleValToObj(input, key = "val") {
    //console.log("arrayEleValToObj", input, key)
    let re = []
    let list = _.concat(input)
    for (let li of list) {
      if (li && !Ti.Util.isNil(li)) {
        // 本来就是对象，那么就直接使用
        if (_.isObject(li) && !Ti.Util.isNil(li[key])) {
          re.push(li)
        }
        // 封装为对象
        else {
          re.push({
            [key]: li
          })
        }
      }
    }
    return re
  },
  //---------------------------------------------------
  // [{$key: Any}] => [Any]
  arrayEleObjToVal(input, key = "val") {
    //console.log("arrayEleObjToVal", input, key)
    let re = []
    let list = _.concat(input)
    for (let li of list) {
      if (li && !Ti.Util.isNil(li[key])) {
        re.push(li[key])
      }
    }
    return re
  },
  //---------------------------------------------------
  rangeToArray(input, dft = "0,100") {
    //console.log(input, dft)
    input = input || dft;
    let vals = _.isArray(input) ? input : Ti.S.splitIgnoreBlank(input);

    let re = [];
    let n = Math.max(vals.length, 2);
    for (let i = 0; i < n; i++) {
      let v = vals[i] * 1;
      if (!isNaN(v)) {
        re.push(v);
      }
    }

    if (_.isEmpty(re)) {
      return [0, 100];
    }
    if (re.length == 1) {
      return [0, re[0]];
    }
    return re;
  },
  textToArray(text) {
    if (text.indexOf("[") != 0) {
      text = "[" + text;
    }
    if (text.lastIndexOf("]") != text.length - 1) {
      text = text + "]";
    }
    return JSON.parse(text);
  },
  arrayToText(array) {
    return JSON.stringify(array, null, 2);
  },
};
return __TI_MOD_EXPORT_VAR_NM;;
})()
// ============================================================
// EXPORT 'lvgl-keyboard.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/keyboard/lvgl-keyboard.mjs'] = (function(){
const _keyboard_Lower = [
  [
    {
      label: "1#",
      width: "3%",
    },
    {
      label: "q",
    },
    {
      label: "w",
    },
    {
      label: "e",
    },
    {
      label: "r",
    },
    {
      label: "t",
    },
    {
      label: "u",
    },
    {
      label: "i",
    },
    {
      label: "o",
    },
    {
      label: "p",
    },
    {
      label: "←",
      width: "3%",
    },
  ],
  [
    {
      label: "ABC",
      width: "8%",
    },
    {
      label: "a",
    },
    {
      label: "d",
    },
    {
      label: "f",
    },
    {
      label: "g",
    },
    {
      label: "h",
    },
    {
      label: "j",
    },
    {
      label: "k",
    },
    {
      label: "l",
    },
    {
      label: "↵",
      width: "8%",
    },
  ],
  [
    {
      label: "_",
    },
    {
      label: "-",
    },
    {
      label: "z",
    },
    {
      label: "x",
    },
    {
      label: "c",
    },
    {
      label: "v",
    },
    {
      label: "b",
    },
    {
      label: "n",
    },
    {
      label: "m",
    },
    {
      label: ".",
    },
    {
      label: ",",
    },
    {
      label: ":",
    },
  ],
  [
    {
      label: "☒",
      text: "取消",
    },
    {
      label: "◀",
    },
    {
      label: " ",
      text: "空格",
      width: "30%",
    },
    {
      label: "▶",
    },
    {
      label: "✔",
      text: "回车",
    },
  ],
];
const _keyboard_Upper = [
  [
    {
      label: "1#",
      width: "3%",
    },
    {
      label: "Q",
    },
    {
      label: "W",
    },
    {
      label: "E",
    },
    {
      label: "R",
    },
    {
      label: "T",
    },
    {
      label: "U",
    },
    {
      label: "I",
    },
    {
      label: "O",
    },
    {
      label: "P",
    },
    {
      label: "←",
      text: "删除",
      width: "3%",
    },
  ],
  [
    {
      label: "abc",
      width: "8%",
    },
    {
      label: "A",
    },
    {
      label: "D",
    },
    {
      label: "F",
    },
    {
      label: "G",
    },
    {
      label: "H",
    },
    {
      label: "J",
    },
    {
      label: "K",
    },
    {
      label: "L",
    },
    {
      label: "↵",
      text: "回车",
      width: "8%",
    },
  ],
  [
    {
      label: "_",
    },
    {
      label: "-",
    },
    {
      label: "Z",
    },
    {
      label: "X",
    },
    {
      label: "C",
    },
    {
      label: "V",
    },
    {
      label: "B",
    },
    {
      label: "N",
    },
    {
      label: "M",
    },
    {
      label: ".",
    },
    {
      label: ",",
    },
    {
      label: ":",
    },
  ],
  [
    {
      label: "☒",
      text: "取消",
    },
    {
      label: "◀",
    },
    {
      label: " ",
      text: "空格",
      width: "30%",
    },
    {
      label: "▶",
    },
    {
      label: "✔",
      text: "回车",
    },
  ],
];

const _keyboard_Special = [
  [
    {
      label: "1",
    },
    {
      label: "2",
    },
    {
      label: "3",
    },
    {
      label: "4",
    },
    {
      label: "5",
    },
    {
      label: "6",
    },
    {
      label: "7",
    },
    {
      label: "8",
    },
    {
      label: "9",
    },
    {
      label: "0",
    },
    {
      label: "←",
      width: "3%",
    },
  ],
  [
    {
      label: "abc",
      width: "8%",
    },
    {
      label: "+",
    },
    {
      label: "-",
    },
    {
      label: "/",
    },
    {
      label: "*",
    },
    {
      label: "=",
    },
    {
      label: "%",
    },
    {
      label: "!",
    },
    {
      label: "?",
    },
    {
      label: "#",
    },
    {
      label: "<",
    },
    {
      label: ">",
    },
  ],
  [
    {
      label: "\\",
    },
    {
      label: "@",
    },
    {
      label: "$",
    },
    {
      label: "(",
    },
    {
      label: ")",
    },
    {
      label: "{",
    },
    {
      label: "}",
    },
    {
      label: "[",
    },
    {
      label: "]",
    },
    {
      label: ";",
    },
    {
      label: '"',
    },
    {
      label: "'",
    },
  ],
  [
    {
      label: "☒",
      text: "取消",
    },
    {
      label: "◀",
    },
    {
      label: " ",
      text: "空格",
      width: "30%",
    },
    {
      label: "▶",
    },
    {
      label: "✔",
      text: "回车",
    },
  ],
];

const _keyboard_Num = [
  [
    {
      label: "1",
    },
    {
      label: "2",
    },
    {
      label: "3",
    },
    {
      label: "☒",
      text: "取消",
      width: "25%",
    },
  ],
  [
    {
      label: "4",
    },
    {
      label: "5",
    },
    {
      label: "6",
    },
    {
      label: "✔",
      text: "回车",
      width: "25%",
    },
  ],
  [
    {
      label: "7",
    },
    {
      label: "8",
    },
    {
      label: "9",
    },
    {
      label: "←",
      text: "删除",
      width: "25%",
    },
  ],
  [
    {
      label: "±",
      text: "正负",
    },
    {
      label: "0",
      text: "零",
    },
    {
      label: ".",
      text: "小数点",
    },
    {
      label: "◀",
      width: "3.5%",
    },
    {
      label: "▶",
      width: "3.5%",
    },
  ],
];

const KeyboardLayout = {
  KEYBOARD_MODE_TEXT_LOWER: _keyboard_Lower,
  KEYBOARD_MODE_TEXT_UPPER: _keyboard_Upper,
  KEYBOARD_MODE_SPECIAL: _keyboard_Special,
  KEYBOARD_MODE_NUM: _keyboard_Num,
};

const _M = {
  ///////////////////////////////////////////////
  props: {
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    mode: {
      type: String,
      default: "KEYBOARD_MODE_TEXT_LOWER",
    },
    heightReal: 0,
    widthReal: 0,
    zoomScale: {
      type: Number,
      default: 1,
    },
  },
  ///////////////////////////////////////////////
  computed: {
    TopClass() {},
    CurrBgStyle() {
      return _.get(this.defaultStatus, "bgPart") || {};
    },
    CurrBtnStyle() {
      return _.get(this.defaultStatus, "btnPart") || {};
    },
    BgStyle() {
      let css = {};
      this.setCssBackgroundStyle(css, this.CurrBgStyle.bg);
      return css;
    },
    BtnLineStyle() {
      let singleHeight = this.heightReal / this.BtnMatrix.length;
      let css = {
        marginBottom: this.heightReal / 40 + "px",
        height: singleHeight + "px",
      };
      return css;
    },
    BtnMatrix() {
      return KeyboardLayout[this.mode] || [];
    },
  },
  ///////////////////////////////////////////////
  methods: {
    getBtnItemStyle(btn) {
      let css = {};
      if (btn.width) {
        css.flexBasis = btn.width;
      }
      this.setCssBackgroundStyle(css, this.CurrBtnStyle.bg);
      return css;
    },
    getBtnLabelStyle(btn) {
      let css = {};
      this.setCssText(css, this.CurrBtnStyle.text, this.zoomScale * 0.8);
      return css;
    },
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-com-loader.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/lvgl-maker-com-loader.mjs'] = (function(){
// 控件分组

// 基础
const GROUP_BASIC = [
  {
    icon: "fas-tag",
    text: "标签",
    value: "LvglLabel",
    path: "core/label",
  },
  {
    icon: "fas-image",
    text: "图片",
    value: "LvglImg",
    path: "core/img",
  },
  {
    icon: "fa-qrcode",
    text: "二维码",
    value: "LvglQrcode",
    path: "core/qrcode",
  },
  {
    icon: "zmdi-comment-alt-text",
    text: "输入文字",
    value: "LvglTextarea",
    path: "core/textarea",
  },
  {
    icon: "fas-keyboard",
    text: "虚拟键盘",
    value: "LvglKeyboard",
    path: "core/keyboard",
  },
  {
    icon: "far-calendar-alt",
    text: "日历",
    value: "LvglCalendar",
    path: "core/calendar",
  },
];

// 按钮
const GROUP_BUTTONS = [
  {
    icon: "fas-hand-point-up",
    text: "普通按钮",
    value: "LvglButton",
    path: "core/button",
  },
  {
    icon: "zmdi-gradient",
    text: "图片按钮",
    value: "LvglImgBtn",
    path: "core/imgbtn",
  },
  {
    icon: "fa-toggle-on",
    text: "开关按钮",
    value: "LvglSwitch",
    path: "core/switch",
  },
  {
    icon: "far-check-square",
    text: "选择框",
    value: "LvglCheckbox",
    path: "core/cb",
  },
  {
    icon: "fas-caret-square-down",
    text: "下拉菜单",
    value: "LvglDropdown",
    path: "core/dropdown",
  },
];

// 容器
const GROUP_CONTAINERS = [
  {
    icon: "zmdi-view-quilt",
    text: "布局容器",
    value: "LvglCont",
    path: "core/cont",
  },
  {
    icon: "fas-scroll",
    text: "页面容器",
    value: "LvglPage",
    path: "core/page",
  },
];

// 进度
const GROUP_PROGRESS = [
  {
    icon: "fas-circle-notch",
    text: "弧",
    value: "LvglArc",
    path: "core/arc",
  },
  {
    icon: "zmdi-ruler",
    text: "进度条",
    value: "LvglBar",
    path: "core/bar",
  },
  {
    icon: "fas-sliders-h",
    text: "滑块",
    value: "LvglSlider",
    path: "core/slider",
  },
  {
    icon: "fas-tachometer-alt",
    text: "仪表盘",
    value: "LvglGauge",
    path: "core/gauge",
  },
  {
    icon: "fas-chart-line",
    text: "图表",
    value: "LvglChart",
    path: "core/chart",
  },
];

// 形状
const GROUP_SHARP = [
  {
    icon: "far-lightbulb",
    text: "LED",
    value: "LvglLed",
    path: "core/led",
  },
];

// 待实现
const GROUP_NOT_IMPL = [
  {
    icon: "zmdi-view-comfy",
    text: "按钮矩阵",
    value: "LvglBtnMatrix",
    path: "core/btnmatrix",
  },
  {
    icon: "fas-palette",
    text: "颜色拾取器",
    value: "LvglCPicker",
    path: "core/cpicker",
  },
];

const _M = {
  //////////////////////////////////////////
  data: () => ({
    hmakerComSetups: {},
  }),
  //////////////////////////////////////////
  computed: {
    LvglComList() {
      let comList = [];
      comList.push({ grp: "基础" });
      comList = comList.concat(GROUP_BASIC);
      comList.push({ grp: "按钮与开关" });
      comList = comList.concat(GROUP_BUTTONS);
      comList.push({ grp: "进度与图表" });
      comList = comList.concat(GROUP_PROGRESS);
      comList.push({ grp: "容器" });
      comList = comList.concat(GROUP_CONTAINERS);
      comList.push({ grp: "特殊形状" });
      comList = comList.concat(GROUP_SHARP);
      return comList;
    },
    //--------------------------------------
    LvglComDict() {
      let re = {};
      _.forEach(this.LvglComList, (com) => {
        re[com.value] = com;
      });
      return re;
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    OnComTypeChange(comType) {
      console.log("lvglMaker change:com:type", comType);
    },
    //--------------------------------------
    async loadComSetup(comType) {
      let comJson = _.get(this.hmakerComSetups, comType);
      //console.log("loadComSetup", comType, comJson)
      if (comJson) {
        return comJson;
      }
      let path = _.get(this.LvglComDict, `${comType}.path`);
      if (!path) {
        return;
      }
      let comPath = `@Site:com/lvgl/${path}/hmaker.json`;
      comJson = await Ti.Load(comPath);
      //console.log("loadComSetup >> ", comPath, comJson)
      this.hmakerComSetups = _.assign({}, this.hmakerComSetups, {
        [comType]: comJson,
      });

      // Preload com
      let app = Ti.App(this);
      await app.loadView({
        comType: `@Site:com/lvgl/${path}`,
      });

      return comJson;
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  watch: {},
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-bar.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/bar/lvgl-bar.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    //-------------------------------------------
    startValue: {
      type: [Number, Array],
      default: 0,
    },
    value: {
      type: [Number, Array],
      default: 0,
    },
    range: {
      type: Array,
      default: () => [0, 100],
    },
    animTime: {
      type: Number,
      default: 500,
    },
    //-------------------------------------------
    // Aspec
    //-------------------------------------------
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    // 这里是 Stage 传入的控件真实宽高
    heightReal: 0,
    widthReal: 0,
  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    BarObj() {
      if (_.isNumber(this.value)) {
        return { val: this.value, animat: false };
      }
      if (_.isArray(this.value)) {
        return {
          val: _.nth(this.value, 0),
          animat: "ANIM_ON" == _.nth(this.value, 1),
        };
      }
      return { val: this.range[0], animat: false };
    },
    //-------------------------------------------
    BarValue() {
      return this.BarObj.val;
    },
    //-------------------------------------------
    CurrBgStyle() {
      return _.get(this.defaultStatus, "bgPart") || {};
    },
    CurrIndicStyle() {
      return _.get(this.defaultStatus, "indicPart") || {};
    },
    PartBgStyle() {
      let bgStyle = this.getCssBackgroundStyle(this.CurrBgStyle.bg || {});
      bgStyle.borderRadius = this.heightReal / 2 + "px";
      bgStyle.overflow = "hidden";
      let bgPad = this.CurrBgStyle ? this.CurrBgStyle.pad : null;
      if (bgPad) {
        Object.keys(bgPad).forEach(
          (pos) =>
            (bgStyle[this.toCamelCase("padding-" + pos)] = bgPad[pos] + "px")
        );
      }
      return bgStyle;
    },
    PartIndicStyle() {
      let currRange = parseInt(this.range[1] - this.range[0]);
      let currValue = parseInt(this.BarValue - this.range[0]);
      let width = (currValue / currRange) * 100 + "%";

      let indicStyle = this.getCssBackgroundStyle(this.CurrIndicStyle.bg || {});
      indicStyle.borderRadius = this.heightReal / 2 + "px";
      indicStyle.width = width;

      if (this.BarObj.animat || this.anim) {
        indicStyle.transition =
          this.animTime > 0 ? `${this.animTime}ms` : "500ms";
      }
      return indicStyle;
    },
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-cpicker.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/cpicker/lvgl-cpicker.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    //-------------------------------------------
    //-------------------------------------------
    // Aspec
    //-------------------------------------------
    
  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------

    //-------------------------------------------
  }
  ///////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-part-support.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/lvgl-part-support.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props: {
    "device": {
      type: Object,
      default: () => ({
        width: 500,
        height: 500
      })
    },
    "screens": {
      type: Array,
      default: () => [
        {
          name: "ScreenA",
          layout: () => ({})
        }
      ]
    },
    "schema": {
      type: Object,
      default: () => ({})
    },
    "currentScreenIndex": {
      type: Number
    },
    "currentBlockName": {
      type: String
    },
    "checkedBlockNames": {
      type: Array,
      default: () => []
    },
    "comList": {
      type: Array,
      default: () => []
    },
    "comSetups": {
      type: Object,
      default: () => ({})
    },
    "projectId": {
      type: String
    },
    "apiBase": {
      type: String
    }
  },
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    LvglScreens() {
      return this.screens || []
    },
    //--------------------------------------
    LvglBlocks() {
      let re = {}
      for (let screen of this.LvglScreens) {
        let blocks = _.get(screen, "layout.blocks")
        this.joinLvglScreenBlocks(re, blocks)
      }
      return re
    },
    //--------------------------------------
    LvglCurrentScreen() {
      return _.nth(this.LvglScreens, this.currentScreenIndex)
    },
    //--------------------------------------
    LvglCurrentBlock() {
      return _.get(this.LvglBlocks, this.currentBlockName)
    },
    //--------------------------------------
    LvglCurrentCom() {
      return _.get(this.schema, this.currentBlockName)
    },
    //--------------------------------------
    LvglCurrentComType() {
      return _.get(this.LvglCurrentCom, "comType")
    },
    //--------------------------------------
    LvglCurrentComConf() {
      return _.get(this.LvglCurrentCom, "comConf")
    },
    //--------------------------------------
    LvglCurrentComSetup() {
      return _.get(this.comSetups, this.LvglCurrentComType)
    },
    //--------------------------------------
    LvglComDict() {
      let re = {}
      _.forEach(this.comList, (com) => {
        re[com.value] = com
      })
      return re
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    joinLvglScreenBlocks(re = {}, blocks = [], axis = []) {
      if (_.isArray(blocks)) {
        let lastI = blocks.length - 1;
        for (let i = 0; i <= lastI; i++) {
          let block = blocks[i]
          block.index = i
          block.axis = axis
          block.depth = axis.length
          block.isFirst = 0 == i
          block.isLast = lastI == i
          block.atTop = lastI == i
          block.atBottom = 0 == i
          // Join Self
          if (block.name) {
            re[block.name] = block
          }
          // Join Children
          this.joinLvglScreenBlocks(re, block.blocks, [...axis, block.name])
        }
      }
    }
    //--------------------------------------
  }
  //////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-style-outline.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/style/outline/lvgl-maker-style-outline.mjs'] = (function(){
////////////////////////////////////////////////////////
const _M = {
  //////////////////////////////////////////////////////
  props: {
    //-----------------------------------
    // Data
    //-----------------------------------
    value: {
      type: Object,
    },
  },
  //////////////////////////////////////////////////////
  computed: {
    //--------------------------------------------------
    StyleForm() {
      return {
        spacing: "comfy",
        fields: [
          {
            title: "线条颜色",
            name: "color",
            comType: "TiInputColor",
            comConf: {
              showAlpha: false,
            },
          },
          {
            title: "不透明度",
            name: "opa",
            type: "Integer",
            defaultAs: 255,
            comType: "TiInputNum",
            comConf: {
              step: 1,
              minValue: 0,
              maxValue: 255,
            },
          },
          {
            title: "轮廓线宽",
            name: "width",
            type: "Integer",
            defaultAs: 0,
            comType: "TiInputNum",
          },
          {
            title: "边距",
            name: "pad",
            type: "Integer",
            defaultAs: 0,
            comType: "TiInputNum",
          },
          {
            title: "混合模式",
            name: "blendMode",
            comType: "TiSwitcher",
            comConf: {
              options: ["NORMAL", "ADDITIVE", "SUBTRACTIVE"],
            },
          },
        ],
      };
    },
    //--------------------------------------------------
  },
  //////////////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-dropdown.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/dropdown/lvgl-dropdown.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    //-------------------------------------------
    options: {
      type: String,
      default: "",
    },
    selected: {
      type: Number,
      default: 0,
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    zoomScale: {
      type: Number,
      default: 1,
    },
  },
  ///////////////////////////////////////////////
  computed: {
    currMainStyle() {
      return _.get(this.defaultStatus, "mainPart") || {};
    },
    //-------------------------------------------
    partMainStyle() {
      let bgStyle = this.getCssBackgroundStyle(this.currMainStyle.bg || {});
      let bgPad = this.currMainStyle ? this.currMainStyle.pad : null;
      if (bgPad) {
        Object.keys(bgPad).forEach(
          (pos) =>
            (bgStyle[this.toCamelCase("padding-" + pos)] = bgPad[pos] + "px")
        );
      }
      this.setCssText(bgStyle, this.currMainStyle.text, this.zoomScale);
      this.setCssBorder(bgStyle, this.currMainStyle.border || {});
      return bgStyle;
    },

    optionsList() {
      if (this.options) {
        return this.options.split("\n");
      }
      return [];
    },

    optionSelected() {
      if (this.selected < this.optionsList.length) {
        return this.optionsList[this.selected];
      } else {
        if (this.optionsList.length == 0) {
          return "无内容";
        } else {
          return "下标错误";
        }
      }
    },
  },
  ///////////////////////////////////////////////
  mounted: function () {
    this.$notify("com:block:resizable", {
      [this.blockName]: "ew-resize",
    });
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-img.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/img/lvgl-img.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  data: () => ({
    myImgSrc: undefined,
    naturalWidth: undefined,
    naturalHeight: undefined,
    imgLoading: false,
  }),
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    //-------------------------------------------
    src: {
      type: String,
      default: "",
    },
    apiBase: {
      type: String,
    },
    projectId: {
      type: String,
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    CurrMainStyle() {
      return _.get(this.defaultStatus, "mainPart") || {};
    },
    //-------------------------------------------
    ImageStyle() {
      let bgStyle = this.getCssBackgroundStyle(this.CurrMainStyle.bg || {});
      return bgStyle;
    },
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    // 图片加载完成，自动读取原始分辨率
    OnImageLoaded() {
      let $img = this.$refs.img;
      if ($img) {
        let w = $img.naturalWidth;
        let h = $img.naturalHeight;
        this.naturalWidth = w;
        this.naturalHeight = h;
        this.imgLoading = false;
        this.$notify("com:block:scale", {
          [this.blockName]: w / h,
        });
        // this.$notify("change:com:conf:data", {
        //   [this.blockName]: {
        //     naturalWidth: w,
        //     naturalHeight: h
        //   }
        // })
        let preld = {
          src: this.src,
          name: this.blockName,
          width: w,
          height: h,
        };
        //console.log("OnImagePreloaded", preld)
        // 这里要在下一个滴答来做，因为上面的 com:block:scale 可能会导致
        // lvgl.screens 里的 block 宽高发生自动改变
        // 而这个改变，LvglMaker 需要通知 Vuex 的模型，这需要一点时间
        // 如果直接通知 img:prloaded，那么 Vuex 的改变还没传递到 LvglMaker 的属性上
        // 就又要通知一次改动，而之前的 screens 的修改会被这次改变覆盖掉
        _.delay(() => {
          this.$notify("img:preloaded", preld);
        });
      }
    },
    //-------------------------------------------
    // 双击，自动恢复图片原始大小
    OnDblClickImage() {
      this.OnImageLoaded();
    },
    //-------------------------------------------
    getImgSrc(src) {
      return new Promise((resolve) => {
        if (Ti.Util.isNil(src)) {
          resolve(null);
        }
        // 来自本地文件 (VSCode)
        else if (_.isFunction(window.vscodeEvalLocalImgSrc)) {
          window.vscodeEvalLocalImgSrc(src, (src2) => {
            resolve(src2);
          });
        }
        // 其他的认为来自本地
        else {
          resolve(
            [
              this.apiBase,
              "project/file/read",
              `?projId=${this.projectId}`,
              `&src=${src}`,
            ].join("")
          );
        }
      });
    },
    //-------------------------------------------
    async evalMyImgSrc(src) {
      // 重置
      if (!src) {
        this.myImgSrc = null;
        this.naturalHeight = undefined;
        this.naturalWidth = undefined;
        this.imgLoading = false;
        return;
      }
      //console.log("evalMyImgSrc", src);
      this.imgLoading = true;
      // 来自网络
      if (/^https?:\/\//.test(src)) {
        this.myImgSrc = src;
        return;
      }

      // 加载图片真实地址：
      // 加载完毕，会触发 OnImageLoaded
      this.myImgSrc = await this.getImgSrc(src);
    },
    //-------------------------------------------
    isSrcInUsed(src) {
      return this.src == src;
    },
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  watch: {
    src: {
      handler: function (newVal, oldVal) {
        if (!_.isEqual(newVal, oldVal)) {
          this.evalMyImgSrc(newVal);
        }
      },
      immediate: true,
    },
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-prop.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/prop/lvgl-maker-prop.mjs'] = (function(){
const KEEP_FROM_NAME_AT = "lvgl-maker-prop-formName";
const KEEP_DFT_PART_AT = "lvgl-maker-prop-comParts";
const _M = {
  //////////////////////////////////////////
  data: () => ({
    myComDftParts: {},
    myFormName: "measure",
    myStatus: "DEFAULT",
    myPart: undefined,
  }),
  //////////////////////////////////////////
  props: {
    currentMeasure: {
      type: Object,
    },
    blockResizable: {
      type: Object,
      default: () => ({}),
    },
    fixedDeviceSize: {
      type: Boolean,
    },
  },
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    TopClass() {
      return this.getTopClass({
        "has-current-screen": this.LvglCurrentScreen ? true : false,
        "has-current-block": this.LvglCurrentBlock ? true : false,
      });
    },
    //--------------------------------------
    isNil() {
      return Ti.Util.isNil(this.LvglCurrentComSetup);
    },
    //--------------------------------------
    DevFormFields() {
      return [
        {
          title: "设备",
        },
        {
          title: "设备宽度",
          name: "dev_width",
          defaultAs: 640,
          type: "Integer",
          comConf: {
            readonly: this.fixedDeviceSize,
          },
        },
        {
          title: "设备高度",
          name: "dev_height",
          defaultAs: 480,
          type: "Integer",
          comConf: {
            readonly: this.fixedDeviceSize,
          },
        },
        {
          title: "设备背景",
          name: "dev_bg",
          type: "Object",
          comType: "LvglMakerStyleBg"
        },
        // {
        //   title: "屏幕旋转",
        //   name: "rotation",
        //   fieldWidth: "100%",
        //   defaultAs: "DISP_ROT_NONE",
        //   comType: "TiDroplist",
        //   comConf: {
        //     options: [
        //       {
        //         value: "DISP_ROT_NONE",
        //         text: "正常",
        //       },
        //       {
        //         value: "DISP_ROT_90",
        //         text: "旋转90度",
        //       },
        //       {
        //         value: "DISP_ROT_180",
        //         text: "旋转180度",
        //       },
        //       {
        //         value: "DISP_ROT_270",
        //         text: "旋转270度",
        //       },
        //     ],
        //   },
        // },
        {
          title: "当前屏幕",
        },
        {
          title: "屏幕名称",
          name: "screenName",
          fieldWidth: "100%",
        },
      ];
    },
    //--------------------------------------
    DevFormData() {
      return {
        dev_width: _.get(this.device, "width"),
        dev_height: _.get(this.device, "height"),
        dev_bg: _.get(this.device, "bg"),
        screenName: _.get(this.LvglCurrentScreen, "name"),
      };
    },
    //--------------------------------------
    ComMeasureFields() {
      let resizable = this.blockResizable[this.currentBlockName];
      let isAutoFit = this.LvglCurrentBlock.autoFit
        && "FIT_NONE" != this.LvglCurrentBlock.autoFit;
      //console.log(this.blockResizable, resizable)
      return [
        {
          title: "排列",
          name: "align",
          comType: "TiDroplist",
          comConf: {
            placeholder: "IN_TOP_LEFT",
            options: [
              "CENTER",
              "IN_TOP_LEFT",
              "IN_TOP_MID",
              "IN_TOP_RIGHT",
              "IN_BOTTOM_LEFT",
              "IN_BOTTOM_MID",
              "IN_BOTTOM_RIGHT",
              "IN_LEFT_MID",
              "IN_RIGHT_MID",
              "OUT_TOP_LEFT",
              "OUT_TOP_MID",
              "OUT_TOP_RIGHT",
              "OUT_BOTTOM_LEFT",
              "OUT_BOTTOM_MID",
              "OUT_BOTTOM_RIGHT",
              "OUT_LEFT_TOP",
              "OUT_LEFT_MID",
              "OUT_LEFT_BOTTOM",
              "OUT_RIGHT_TOP",
              "OUT_RIGHT_MID",
              "OUT_RIGHT_BOTTOM"
            ],
            dropDisplay: "text",
          },
        },
        {
          title: "宽度",
          name: "width",
          type: "Integer",
          hidden: isAutoFit || /^(auto|ns-resize)$/.test(resizable)
        },
        {
          title: "宽度",
          name: "width",
          visible: isAutoFit || /^(auto|ns-resize)$/.test(resizable),
          comType: "TiLabel",
          comConf: {
            value: "自动",
          },
        },
        {
          title: "高度",
          name: "height",
          type: "Integer",
          hidden: isAutoFit || /^(auto|ew-resize)$/.test(resizable),
        },
        {
          title: "高度",
          name: "height",
          visible: isAutoFit || /^(auto|ew-resize)$/.test(resizable),
          comType: "TiLabel",
          comConf: {
            value: "自动",
          },
        },
        {
          title: "X轴",
          name: "x",
          type: "Integer",
          // disabled: {
          //   "!align": "[BLANK]",
          // },
        },
        {
          title: "Y轴",
          name: "y",
          type: "Integer",
          // disabled: {
          //   "!align": "[BLANK]",
          // },
        },
      ];
    },
    //--------------------------------------
    ComPartStyleFields() {
      let setup = _.get(this.comSetups, this.LvglCurrentComType) || {};
      if (!setup) {
        return;
      }
      let { comTransition, comStatus, comParts } = setup;
      let fields = [];

      // 控件状态
      if (_.isArray(comStatus) && comStatus.length > 1) {
        fields.push({
          title: "状态",
          name: "status",
          comType: "TiDroplist",
          comConf: {
            placeholder: "请选择要编辑的状态",
            options: comStatus,
          },
        });
      }

      // Part 列表
      if (_.isArray(comParts) && comParts.length > 1) {
        fields.push({
          title: "部件",
          name: "part",
          comType: "TiSwitcher",
          comConf: {
            options: comParts,
            allowEmpty: false,
          },
        });
      }

      // 当前 Part 的字段
      let partFieldsKey = _.camelCase(`${this.myPart}_PART_FIELDS`);
      let partFields = _.get(setup, partFieldsKey);
      if (!_.isEmpty(partFields)) {
        fields.push(...partFields);
      }

      // 过渡
      if (comTransition) {
        fields.push({
          title: "过渡",
          icon: "fas-stopwatch",
          name: "transition",
          type: "Object",
          comType: "LvglMakerStyleTransition",
        });
      }

      // 搞定
      return fields;
    },
    //--------------------------------------
    ComPropFields() {
      let setup = _.get(this.comSetups, this.LvglCurrentComType) || {};
      if (!setup) {
        return;
      }
      let { propFields } = setup;
      if (!_.isEmpty(propFields)) {
        return propFields;
      }
    },
    //--------------------------------------
    ComEventFields() {
      let setup = _.get(this.comSetups, this.LvglCurrentComType) || {};
      if (!setup) {
        return;
      }
      let { comEvents } = setup;
      if (_.isEmpty(comEvents)) {
        return;
      }
      // 展开标准字段
      let fields = [];
      _.forEach(comEvents, (ev) => {
        if ("#GENERIC_EVENTS" == ev) {
          fields.push(
            { name: "CLICKED" },
            { name: "PRESSED" },
            { name: "PRESSING" },
            { name: "PRESS_LOST" },
            { name: "SHORT_CLICKED" },
            { name: "LONG_PRESSED" },
            { name: "LONG_PRESSED_REPEAT" },
            { name: "RELEASED" }
          );
        } else {
          fields.push({ name: ev });
        }
      });
      // 设置默认 title
      _.forEach(fields, (fld) => {
        fld.title = `i18n:lvgl-event-${fld.name}`;
        fld.type = "Object";
        fld.tip = fld.name;
        fld.fieldWidth = "100%";
        fld.width = "full";
        fld.comType = "LvglMakerFormEvent";
        fld.comConf = {};
      });
      // 搞定
      return fields;
    },
    //--------------------------------------
    ComFormList() {
      let list = [
        {
          icon: "fas-ruler-combined",
          text: "尺寸",
          value: "measure",
          gridColumnHint: 1,
          fieldNameWidth: [
            ["0.5rem", "en-us"],
            ["0.6rem"]
          ],
          fields: this.ComMeasureFields,
        },
        {
          icon: "fas-palette",
          text: "外观",
          value: "partStyle",
          gridColumnHint: 0,
          fields: this.ComPartStyleFields,
        },
      ];
      // 控件内置属性
      if (!_.isEmpty(this.ComPropFields)) {
        list.push({
          icon: "zmdi-gamepad",
          text: "属性",
          value: "prop",
          fieldValueWrap: "wrap",
          fields: this.ComPropFields,
        });
      }
      // 控件事件
      if (!_.isEmpty(this.ComEventFields)) {
        list.push({
          icon: "zmdi-flash",
          text: "事件",
          value: "events",
          fieldNameVAlign: "top",
          fieldNameWidth: [
            ["1.2rem", "en-us"],
            ["0.9rem"]
          ],
          fieldValueWrap: "wrap",
          fields: this.ComEventFields,
        });
      }
      return list;
    },
    //--------------------------------------
    ComCurrentFormConf() {
      if (_.isEmpty(this.ComFormList)) {
        return;
      }
      // 确保再列表中
      let fli = _.find(this.ComFormList, (cf) => cf.value == this.myFormName);
      if (!fli) {
        fli = _.first(this.ComFormList);
      }
      return _.omit(fli, "icon", "text", "value");
    },
    //--------------------------------------
    ComCurrentFormData() {
      //....................................
      //【尺寸】数据
      if ("measure" == this.myFormName) {
        let { x, y, width, height, align, depth } = this.LvglCurrentBlock;
        let mea = this.currentMeasure || {};
        return _.assign({ x, y, width, height, align, depth }, mea);
      }
      //....................................
      //【外观】数据
      else if ("partStyle" == this.myFormName) {
        let comConf = _.cloneDeep(this.LvglCurrentComConf);
        let partKey = this.getPartStyleKey();
        let partStyle = _.get(comConf, partKey);
        let transition = _.get(comConf, "transition");
        return {
          status: this.myStatus,
          part: this.myPart,
          partStyle,
          transition,
        };
      }
      //....................................
      //【属性】数据
      else if ("prop" == this.myFormName) {
        let comConf = _.cloneDeep(this.LvglCurrentComConf);
        let prop = {};
        _.forEach(comConf, (v, k) => {
          // 无视这些属性
          if (/^(status|transition|.+(Status|Part))$/.test(k)) {
            return;
          }
          // 其他的属性，复制之
          prop[k] = v;
        });
        return prop;
      }
      //....................................
      //【事件】数据
      else if ("events" == this.myFormName) {
        let comConf = _.cloneDeep(this.LvglCurrentComConf);
        return _.get(comConf, "events");
      }
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    OnTabChange(formName) {
      this.myFormName = formName;
      Ti.Storage.local.set(KEEP_FROM_NAME_AT, formName);
    },
    //--------------------------------------
    OnCurrentBlockNameChange(newName) {
      this.$notify("change:block:name", {
        newVal: newName,
        oldVal: _.get(this.LvglCurrentBlock, "name"),
      });
    },
    //--------------------------------------
    OnDevFormFieldChange({ name, value }) {
      // Device
      let m = /^dev_(width|height|bg)$/.exec(name);
      if (m) {
        this.$notify("change:device", {
          [m[1]]: value,
        });
      }
      // Screen
      else if ("screenName" == name) {
        this.$notify("change:screen:name", value);
      }
    },
    //--------------------------------------
    OnComFormFieldChange({ name, value }) {
      //....................................
      //【尺寸】数据
      if ("measure" == this.myFormName) {
        this.$notify("change:block:prop", { name, value });
      }
      //....................................
      //【外观】数据
      else if ("partStyle" == this.myFormName) {
        let m = /^partStyle\.(.+)$/.exec(name);
        if (m) {
          let partKey = this.getPartStyleKey();
          let name2 = `${partKey}.${m[1]}`;
          this.$notify("change:com:conf", { name: name2, value });
        }
        // Status
        else if ("status" == name) {
          this.myStatus = value;
          this.$notify("change:com:conf", { name, value });
        }
        // Part
        else if ("part" == name) {
          this.myPart = value;

          // 缓存到本地
          this.saveCurrentPartToLocal(value)
        }
        // 否则就是普通外观属性
        else {
          this.$notify("change:com:conf", { name, value });
        }
      }
      //....................................
      //【属性】数据
      else if ("prop" == this.myFormName) {
        this.$notify("change:com:conf", { name, value });
      }
      //....................................
      //【事件】数据
      else if ("events" == this.myFormName) {
        let comConf = _.cloneDeep(this.LvglCurrentComConf);
        let events = _.get(comConf, "events") || {};
        events[name] = value;
        //console.log({ events });
        this.$notify("change:com:conf", { name: "events", value: events });
      }
    },
    //--------------------------------------
    OnFormChange() { },
    //--------------------------------------
    getPartStyleKey({ part = this.myPart, status = this.myStatus } = {}) {
      return [`${_.camelCase(status)}Status`, `${_.camelCase(part)}Part`].join(
        "."
      );
    },
    //--------------------------------------
    saveCurrentPartToLocal(part) {
      if (this.LvglCurrentComType && part) {
        this.myComDftParts = _.assign({}, this.myComDftParts, {
          [this.LvglCurrentComType]: part
        })
        Ti.Storage.local.setObject(KEEP_DFT_PART_AT, this.myComDftParts)
      }
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  watch: {
    "LvglCurrentComConf": {
      handler: function (newVal, oldVal) {
        let setup = _.get(this.comSetups, this.LvglCurrentComType);
        if (setup && newVal && (!oldVal || !_.isEqual(newVal, oldVal))) {
          let comConf = newVal;
          this.myPart = _.get(this.myComDftParts, this.LvglCurrentComType)
            || setup.defaultPart
            || "MAIN";
          this.myStatus = comConf.status || setup.defaultStatus || "DEFAULT";
        }
      },
    },
  },
  //////////////////////////////////////////
  created: function () {
    this.myFormName = Ti.Storage.local.getString(KEEP_FROM_NAME_AT) || "measure";
    this.myComDftParts = Ti.Storage.local.getObject(KEEP_DFT_PART_AT) || {};
  },
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'wb-head.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/workbench/head/wb-head.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props: {
    "icon": {
      type: String,
      default: "im-diamond-o"
    },
    "project": {
      type: Object,
      default: () => ({})
    },
    "file": {
      type: Object,
      default: () => ({})
    }
  },
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    hasProject() {
      return !_.isEmpty(this.project)
    },
    //--------------------------------------
    hasFile() {
      return !_.isEmpty(this.file)
    },
    //--------------------------------------
    ProjectIcon() {
      return _.get(this.project, "icon") || this.icon
    },
    //--------------------------------------
    ProjectTitle() {
      return Ti.Util.getFallbackNil(this.project, "title", "nm", "id")
    },
    //--------------------------------------
    FileName() {
      return Ti.Util.getFallbackNil(this.file, "title", "nm", "id")
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    //--------------------------------------
  }
  //////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-form-event.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/form/event/lvgl-maker-form-event.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props: {
    value: {
      type: [String, Object],
    },
  },
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    ValObj() {
      if (_.isEmpty(this.value)) {
        return { type: "invoke" };
      }
      if (_.isString(this.value)) {
        return { type: "invoke", name: this.value };
      }
      return this.value;
    },
    //--------------------------------------
    ValType() {
      return this.ValObj.type;
    },
    //--------------------------------------
    ValName() {
      return this.ValObj.name;
    },
    //--------------------------------------
    TypeOptions() {
      return [
        {
          text: "函数",
          value: "invoke",
        },
        {
          text: "屏幕",
          value: "screen",
        },
      ];
    },
    //--------------------------------------
    ScreenNames() {
      let $maker = this.tiParentCom("LvglMaker");
      let names = [];
      _.forEach($maker.myDataScreens, ({ name }) => {
        names.push(name);
      });
      return names;
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    OnValTypeChange(valType = "invoke") {
      let val = _.cloneDeep(this.ValObj);
      val.type = valType;
      this.$notify("change", val);
    },
    //--------------------------------------
    OnValNameChange(valName) {
      let val = _.cloneDeep(this.ValObj);
      val.name = valName;
      // 校验 name 有消息
      if (!/^[a-zA-Z_][a-zA-Z0-9_]+$/.test(val.name)) {
        Ti.Toast.Open(
          "函数名称只能是英文数字或者下划线，并且不能以数字开头",
          "warn",
          "top"
        );
        return;
      }
      this.$notify("change", val);
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'wb-arena.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/workbench/com/wb-arena/wb-arena.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props: {
    "meta": {
      type: Object,
      default: undefined
    },
    "content": {
      type: String
    },
    "list": {
      type: Array,
      default: () => []
    },
    "currentId": {
      type: String
    },
    "checkedIds": {
      type: [Array, Object]
    },
    "projectId": {
      type: String
    },
  },
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    isEmpty() { return this.meta ? false : true },
    //--------------------------------------
    isLVGL() {
      return "lvgl" == this.meta.tp
    },
    //--------------------------------------
    isDIR() {
      return "DIR" == this.meta.race
    },
    //--------------------------------------
    AdaptListRounters() {
      return {
        "reload": "dispatch:edit/reloadCurrentDirList"
      }
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    async OnOpenImage(oImg) {
      let src = Ti.WWW.evalObjPreviewSrc(oImg, {
        previewKey: "..",
        previewObj: "..",
        apiTmpl: `${this.apiBase}media?\${thumb}`,
        cdnTmpl: this.cdnTmpl
      })
      let link = Ti.Util.parseHref(src)
      console.log(link)
      let path = link.toUrlPath()
      Ti.Be.Open(path, { params: link.params })
    },
    //--------------------------------------
    FileThumbBy(meta, {
      exposeHidden = false,
      status = {},
      progress = {},
      badges = undefined,
      titleKey = "title|nm"
    }) {
      let previewSrc = Ti.WWW.evalObjPreviewSrc(meta, {
        previewKey: "thumb",
        previewObj: "thumb_obj",
        apiTmpl: `${this.apiBase}media?\${thumb}`,
        cdnTmpl: this.cdnTmpl
      })
      let fileSrc = Ti.WWW.evalObjPreviewSrc(meta, {
        previewKey: "..",
        previewObj: "..",
        apiTmpl: `${this.apiBase}media?\${thumb}`,
        cdnTmpl: this.cdnTmpl
      })
      let obj = {
        id: meta.id,
        nm: meta.nm,
        title: Ti.Util.getOrPick(meta, titleKey),
        preview: {
          type: "image",
          value: previewSrc
        },
        href: fileSrc,
        visibility: "show",
        badges,
        rawData: meta
      }
      return obj
    },
    //--------------------------------------
    async FileUploadBy(file, { progress } = {}) {
      return await Ti.App(this).dispatch("edit/uploadFileToCurrentDir", {
        file, progress
      })
    }
    //--------------------------------------
  }
  //////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-methods.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/lvgl-methods.mjs'] = (function(){
const __TI_MOD_EXPORT_VAR_NM = {
  //--------------------------------------
  getCssColor(color, opa = 255) {
    if (color) {
      let c = Ti.Types.toColor(color);
      c.alpha = opa / 255;
      return c.toString();
    }
  },
  //--------------------------------------
  setCssNumberProp(css = {}, key, val) {
    if (key && val) {
      let k = _.kebabCase(key);
      let v = Ti.Css.toSize(val, { autoPercent: false });
      css[k] = v;
    }
  },
  //--------------------------------------
  setCssTextDecoration(css = {}, decor) {
    if ("STRIKETHROUGH" == decor) {
      css.textDecoration = "line-through";
    } else {
      css.textDecoration = _.toLower(decor || "none");
    }
  },
  //--------------------------------------
  setCssBlendMode(css = {}, blendMode) {
    if ("ADDITIVE" == blendMode) {
      css.mixBlendMode = "overlay";
    }
    // Blend mode: SUBTRACTIVE
    else if ("SUBTRACTIVE" == blendMode) {
      css.mixBlendMode = "difference";
    }
  },
  //--------------------------------------
  setCssBorder(css = {}, border = {}) {
    let { color, opa, width, side } = border;
    if (width > 0) {
      css.borderColor = this.getCssColor(color, opa);
      css.borderStyle = "solid";
      // 边框 side
      let borderSides = _.concat(side);
      let w = Ti.Css.toSize2(width);
      // 所有边框
      if (_.indexOf(borderSides, "FULL") >= 0) {
        css.borderWidth = w;
      }
      // 看看指定的边框
      else {
        css.borderWidth = "inherit";
        for (let bs of borderSides) {
          let k = {
            LEFT: "borderLeftWidth",
            RIGHT: "borderRightWidth",
            TOP: "borderTopWidth",
            BOTTOM: "borderBottomWidth",
          }[bs];
          css[k] = w;
        }
      }
    }
  },
  //--------------------------------------
  setCssText(css = {}, text = {}, zoomScale = 1) {
    let {
      color,
      opa,
      letterSpace,
      lineSpace,
      ofsX,
      ofsY,
      blendMode,
      decor,
      font,
    } = text || {};
    //.........................................
    css.color = this.getCssColor(color, opa);
    this.setCssNumberProp(css, "letterSpacing", letterSpace);
    this.setCssNumberProp(css, "lineHeight", lineSpace);
    this.setCssNumberProp(css, "left", ofsX);
    this.setCssNumberProp(css, "top", ofsY);
    this.setCssTextDecoration(css, decor);
    this.setCssFont(css, font, zoomScale);
    this.setCssBlendMode(css, blendMode);
  },
  //--------------------------------------
  setCssPad(css = {}, pad = {}) {
    this.setCssNumberProp(css, "paddingTop", pad.top);
    this.setCssNumberProp(css, "paddingRight", pad.right);
    this.setCssNumberProp(css, "paddingBottom", pad.bottom);
    this.setCssNumberProp(css, "paddingLeft", pad.left);
  },
  //--------------------------------------
  setCssFont(css = {}, font = {}, zoomScale = 1) {
    let { size, weight, name } = font;
    css.fontFamily = name || "SimSun";
    css.fontSize = (size || 16) * zoomScale + "px";
    css.fontWeight = "normal";
    if (weight == "LIGHT") {
      css.fontWeight = "lighter";
    }
    if (weight == "HEAVY") {
      css.fontWeight = "bold";
    }
  },
  //--------------------------------------
  setCssOutline(css = {}, border = {}) {
    let { color, opa, width, pad, blendMode } = border;
    css.outlineColor = this.getCssColor(color, opa);
    css.outlineStyle = "solid";
    css.outlineWidth = Ti.Css.toSize2(width) || "0px";
    css.outlineOffset = Ti.Css.toSize2(pad) || "0px";
    this.setCssBlendMode(css, blendMode);
  },
  //--------------------------------------
  setCssShadow(css = {}, border = {}) {
    let { color, opa, width = 0, ofsX = 0, ofsY = 0, spread = 0 } = border;
    let sd_color = this.getCssColor(color, opa);
    if (sd_color) {
      let w = Ti.Css.toSize2(width);
      let x = Ti.Css.toSize2(ofsX);
      let y = Ti.Css.toSize2(ofsY);
      let s = Ti.Css.toSize2(spread);
      css.boxShadow = [x, y, w, s, sd_color].join(" ");
    }
  },
  //--------------------------------------
  setCssTransition(css = {}, transition = {}) {
    let { time, delay = 0, prop = [] } = transition;
    if (time > 0 && prop.length > 0) {
      css.transitionDuration = `${time}ms`;
      css.transitionDelay = `${delay}ms`;
      css.transitionProperty = _.map(prop, (name) => {
        return (
          {
            WIDTH: "width",
            HEIGHT: "height",
            X: "left",
            Y: "top",
            PAD_TOP: "padding-top",
            PAD_BOTTOM: "padding-bottom",
            PAD_LEFT: "padding-left",
            PAD_RIGHT: "padding-right",
            BG_COLOR: "background-color",
            BG_OPA: "opacity",
            BORDER_COLOR: "border-color",
            BORDER_WIDTH: "border-width",
            SHADOW: "box-shadow",
            TEXT_COLOR: "color",
            TEXT_OPA: "opacity",
            RADIUS: "border-radius",
            OPA: "opacity",
          }[name] || ""
        );
      }).join(",");
    }
  },
  //--------------------------------------
  setCssBackgroundStyle(css = {}, bg) {
    let bgCss = this.getCssBackgroundStyle(bg);
    _.assign(css, bgCss);
  },
  //--------------------------------------
  getCssBackgroundStyle(bg = {}) {
    let { color, opa, gradColor, mainStop, gradStop, gradDir, blendMode } =
      bg || {};
    let css = {};
    mainStop = mainStop || 0;
    gradStop = gradStop || 255;
    // linear gradient background
    if (color && gradColor) {
      let from = _.clamp(mainStop / 255, 0, 1);
      let to = _.clamp(gradStop / 255, 0, 1);
      let fromP = Ti.S.toPercent(from);
      let toP = Ti.S.toPercent(to);
      // linear-gradient(to right, #333 50%, #eee 75%);
      let grad = [];
      // Verticle
      if ("VER" == gradDir) {
        grad.push("to bottom");
      }
      // Horizontal
      else if ("HOR" == gradDir) {
        grad.push("to right");
      }
      grad.push(`${color} ${fromP}`);
      grad.push(`${gradColor} ${toP}`);
      css.backgroundImage = `linear-gradient(${grad.join(",")})`;
      //
      // Opacity
      //
      if (!Ti.Util.isNil(opa)) {
        css.opacity = opa / 255;
      }
    } else if (color) {
      css.backgroundColor = color;

      if (!Ti.Util.isNil(opa)) {
        let ncolor = Ti.Types.toColor(color);
        ncolor.alpha = opa / 255;
        css.backgroundColor = ncolor.toString();
      }
    }
    //
    // Blend mode: ADDITIVE
    //
    this.setCssBlendMode(css, blendMode);
    // All Done
    return css;
  },
  //--------------------------------------
  setCssLineStyle(css = {}, line) {
    let lineCss = this.getCssLineStyle(line);
    _.assign(css, lineCss);
  },
  //--------------------------------------
  getCssLineStyle(line = {}) {
    let { color, opa, width, rounded } = line;
    let css = {};

    if (color) {
      css.stroke = color;
    }
    if (!Ti.Util.isNil(opa)) {
      css.strokeOpacity = opa / 255;
    }
    if (width) {
      css.strokeWidth = width + "px";
    }
    if (rounded) {
      css.strokeLinecap = "round";
    }

    // All Done
    return css;
  },
  //--------------------------------------
}
return __TI_MOD_EXPORT_VAR_NM;;
})()
// ============================================================
// EXPORT 'lvgl-maker.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/lvgl-maker.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  provide: function () {
    return {
      $maker: this,
    };
  },
  //////////////////////////////////////////
  data: () => ({
    myDataDevice: {},
    myDataScreens: [],
    myDataSchema: {},
    myDataResources: {},
    myCurrentScreenIndex: 0,
    myCurrentBlockName: undefined,

    myCheckedBlockNames: [],

    myCurrentBlockMeasure: {},
    myCurrentBlockForceRatio: false,

    myCopiedBlock: undefined,
    myCopiedCount: 0,

    showBlockOutline: false,
    showIndicateIcon: false,
    showBlockType: false,
    showBlockName: false,

    showOutlinePanel: false,
    showScreenRotation: false,

    /*指示 stage 是否进行拖拽*/
    stageInDragging: false,

    /* {[blockName]: whr} */
    myBlockScales: {},

    /*{[blockName]: true | "auto"}*/
    myBlockResizable: {},

    /*控件都注册到这里*/
    myComDict: {}
  }),
  //////////////////////////////////////////
  props: {
    value: {
      type: [String, Object],
    },
    valueWatcher: {
      type: [String, Function],
    },
    projectId: {
      type: String,
    },
    apiBase: {
      type: String,
    },
    keepSettingTo: {
      type: String,
      default: "lvgl-maker-local-setup",
    },
    fixedDeviceSize: {
      type: Boolean,
      default: false,
    },
  },
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    isInVsCode() {
      return _.isFunction(window.vscodeEvalLocalImgSrc);
    },
    //--------------------------------------
    ContentData() {
      let cd = null;
      if (_.isString(this.value)) {
        if (Ti.Util.isBlank(this.value)) {
          cd = {};
        } else {
          cd = JSON.parse(this.value);
        }
      } else {
        cd = this.value || {};
      }
      return cd;
    },
    //--------------------------------------
    FnValueWatcher() {
      if (_.isFunction(this.valueWatcher)) {
        return this.valueWatcher;
      }
      if (_.isString(this.valueWatcher)) {
        return Ti.Util.genInvoking(this.valueWatcher);
      }
      return () => false;
    },
    //--------------------------------------
    hasCurrentScreen() {
      return this.CurrentScreen ? true : false;
    },
    //--------------------------------------
    CurrentScreen() {
      return _.nth(this.myDataScreens, this.myCurrentScreenIndex);
    },
    //--------------------------------------
    CurrentBlock() {
      return _.get(this.ScreenBlockDict, this.myCurrentBlockName);
    },
    //--------------------------------------
    // 获得一个宽高比，如果并未指定，则采用之前的比例
    CurrentBlockScale() {
      if (this.myCurrentBlockForceRatio && this.CurrentBlock) {
        // 控件指定了宽高比
        let whr = this.myBlockScales[this.myCurrentBlockName];
        if (whr > 0) {
          return whr;
        }
        // 采用之前默认的宽高比
        let { width, height } = this.CurrentBlock;
        return width / height;
      }
      return 0;
    },
    //--------------------------------------
    GUILayout() {
      return {
        type: "cols",
        border: true,
        keepCustomizedTo: "Minke-LvglMaker-Layout-Main-Col",
        blocks: [
          {
            type: "rows",
            border: true,
            blocks: [
              {
                name: "menu",
                size: ".43rem",
                body: "menu",
              },
              {
                name: "stage",
                body: "stage",
              },
            ],
          },
          {
            icon: "zmdi-zmdi-info-outline",
            title: "组件属性",
            size: "30%",
            minSize: 320,
            name: "prop",
            body: "prop",
          },
        ],
        panels: [
          {
            name: "outline",
            title: "组件大纲",
            icon: "fas-sitemap",
            body: "outline",
            position: "right",
            width: "38%",
            height: "100%",
            mask: false,
            closer: "default",
          },
        ],
      };
    },
    //--------------------------------------
    GUISchema() {
      return {
        menu: {
          comType: "TiActionbar",
          comConf: {
            items: this.MenuItems,
            status: {
              hasCurrentScreen: this.hasCurrentScreen,
              hasCurrentBlock: this.myCurrentBlockName ? true : false,
              hasCheckedBlocks: !_.isEmpty(this.myCheckedBlockNames),
              hasCopiedBlock: this.hasCopiedBlock,
              showScreenRotation: this.showScreenRotation,
              showBlockOutline: this.showBlockOutline,
              showIndicateIcon: this.showIndicateIcon,
              showBlockType: this.showBlockType,
              showBlockName: this.showBlockName,
            },
          },
        },
        stage: {
          comType: "LvglMakerStage",
          comConf: {
            device: this.myDataDevice,
            screens: this.myDataScreens,
            schema: this.myDataSchema,
            currentScreenIndex: this.myCurrentScreenIndex,
            currentBlockName: this.myCurrentBlockName,
            checkedBlockNames: this.myCheckedBlockNames,

            comList: this.LvglComList,
            comSetups: this.hmakerComSetups,

            projectId: this.projectId,
            apiBase: this.apiBase,

            blockScale: this.CurrentBlockScale,
            blockResizable: this.myBlockResizable,
            lvglResources: this.myDataResources,

            showBlockOutline: this.showBlockOutline,
            showIndicateIcon: this.showIndicateIcon,
            showBlockType: this.showBlockType,
            showBlockName: this.showBlockName,

            showOutlinePanel: this.showOutlinePanel,
            showScreenRotation: this.showScreenRotation,
          },
        },
        prop: {
          comType: "LvglMakerProp",
          comConf: {
            device: this.myDataDevice,
            screens: this.myDataScreens,
            schema: this.myDataSchema,
            currentScreenIndex: this.myCurrentScreenIndex,
            currentBlockName: this.myCurrentBlockName,
            checkedBlockNames: this.myCheckedBlockNames,

            comList: this.LvglComList,
            comSetups: this.hmakerComSetups,

            currentMeasure: this.myCurrentBlockMeasure,
            blockResizable: this.myBlockResizable,
            fixedDeviceSize: this.fixedDeviceSize,
          },
        },
        outline: {
          comType: "LvglMakerOutline",
          comConf: {
            device: this.myDataDevice,
            screens: this.myDataScreens,
            schema: this.myDataSchema,
            currentScreenIndex: this.myCurrentScreenIndex,
            currentBlockName: this.myCurrentBlockName,
            checkedBlockNames: this.myCheckedBlockNames,

            comList: this.LvglComList,
            comSetups: this.hmakerComSetups,
          },
        },
      };
    },
    //--------------------------------------
    GUIShown() {
      return {
        outline: this.showOutlinePanel,
      };
    },
    //--------------------------------------
    // 编制块名与块实体的字典
    ScreenBlockDict() {
      let re = {};
      const joinBlocks = function (blocks = [], axis = []) {
        let lastI = blocks.length - 1;
        for (let i = 0; i < blocks.length; i++) {
          let block = blocks[i];
          block.index = i;
          block.axis = axis;
          block.depth = axis.length;
          block.isFirst = 0 == i;
          block.isLast = lastI == i;
          block.atTop = lastI == i;
          block.atBottom = 0 == i;
          if (block.name) {
            re[block.name] = block;
          }
          joinBlocks(block.blocks, [...axis, block.name]);
        }
      };
      _.forEach(this.myDataScreens, (screen) => {
        joinBlocks(_.get(screen, "layout.blocks"));
      });
      return re;
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    OnStageImagePreloaded(payload) {
      //console.log("OnStageImagePreloaded", payload)
      let { name, src, keep_src, width, height, autoResizeOff } = payload;
      let screens = null;
      let resources = _.cloneDeep(this.myDataResources) || {};
      let rsIt = resources[src];
      let resizeIt = autoResizeOff ? false : true;
      // 在 Resource 初始化一个设定
      if (!rsIt) {
        resources[src] = {
          type: "image",
          names: [name],
          width,
          height,
        };
      }
      // 已经存在的资源，记入新的名称
      else {
        // 已经存在的组件，那就不要更新宽高了
        if (rsIt.names.find((nm) => nm == name)) {
          resizeIt = false;
        }
        rsIt.names.push(name);
        rsIt.names = _.uniq(rsIt.names);
      }

      //
      // 遍历 reousrce，以便清除老资源的引用
      //
      this.doQuickCleanResource(resources, { src, keep_src, name });

      // 更新下图片的宽高，使用原始大小
      if (resizeIt) {
        screens = this.createUpdateScreenBlocksProp({
          [name]: {
            width,
            height,
          },
        });
      }

      // 统一更新
      this.notifyChange({ screens, resources }, true);
    },
    //--------------------------------------
    doQuickCleanResource(resources, { src, keep_src, name } = {}) {
      let removeSrcs = []
      // 判断
      _.forEach(resources, (res, reSrc) => {
        // 忽略当前给定的 src
        if (reSrc == src) {
          return
        }
        // imgbtn 控件是多个 src，因此它会用另外一个属性告知自己全部的 src
        // 这些 src 统统不删
        if (_.indexOf(keep_src, reSrc) >= 0) {
          return
        }
        // 这个 src 不再被当前块引用了，看看是否需要删除
        res.names = _.without(res.names, name)
        if (_.isEmpty(res.names)) {
          removeSrcs.push(reSrc)
        }
      })
      // 删除
      for (let rmsrc of removeSrcs) {
        delete resources[rmsrc]
      }
    },
    //--------------------------------------
    doCleanUnusedResource() {
      //console.log("doCleanUnusedResource")
      let lvgl = this.getLvglData();
      let resources = _.cloneDeep(lvgl.resources)
      let deleteKeys = []
      _.forEach(resources, (it, src) => {
        let newNames = []
        // 逐个询问控件
        if (!_.isEmpty(it.names)) {
          for (let blockName of it.names) {
            // 在哪个屏幕里呢？
            let screeIndex = this.findScreenIndexByBlock(blockName)
            // 如果不在任何一个屏幕里，那么就是需要移除咯
            if (screeIndex < 0) {
              continue;
            }
            // 如果在当前屏幕里，则根据控件判断
            if (this.myCurrentScreenIndex == screeIndex) {
              let $com = this.myComDict[blockName]
              if ($com && _.isFunction($com.isSrcInUsed)) {
                if ($com.isSrcInUsed(src)) {
                  newNames.push(blockName)
                }
              }
            }
            // 如果不在当前屏幕里，则原样 Copy
            else {
              newNames.push(blockName)
            }
          }
        }
        // 是否需要删除
        if (_.isEmpty(newNames)) {
          deleteKeys.push(src)
        }
        // 更新 names
        else {
          it.names = _.uniq(newNames)
        }
      })
      // 删除悬空的资源记录
      for (let dk of deleteKeys) {
        delete resources[dk]
      }
      // 判断是否需要更新
      if (!_.isEqual(lvgl.resources, resources)) {
        lvgl.resources = resources;
        let content = JSON.stringify(lvgl, null, "  ");
        // 通知变动
        this.$notify("change", content);
        // Watch value
        this.FnValueWatcher(lvgl);
      }
    },
    //--------------------------------------
    OnGuiBlockHide(blockName) {
      if ("outline" == blockName) {
        this.showOutlinePanel = false;
      }
    },
    //--------------------------------------
    OnPreviewLvgl() {
      this.doPreviewLvgl();
    },
    //--------------------------------------
    // 是否显示组件的大纲面板
    OnToggleOutlinePanel() {
      this.showOutlinePanel = !this.showOutlinePanel;
    },
    // 是否显示屏幕旋转方向
    OnToggleShowScreenRotation() {
      this.showScreenRotation = !this.showScreenRotation;
      this.saveLocalSetting();
    },
    // 是否显示组件的轮廓线
    OnToggleShowBlockOutline() {
      this.showBlockOutline = !this.showBlockOutline;
      this.saveLocalSetting();
    },
    //--------------------------------------
    OnToggleShowIndicateIcon() {
      this.showIndicateIcon = !this.showIndicateIcon;
      this.saveLocalSetting();
    },
    //--------------------------------------
    OnToggleShowBlockType() {
      this.showBlockType = !this.showBlockType;
      this.saveLocalSetting();
    },
    //--------------------------------------
    OnToggleShowBlockName() {
      this.showBlockName = !this.showBlockName;
      this.saveLocalSetting();
    },
    //--------------------------------------
    OnToggleBlockVisibility({ blockName }) {
      this.updateCurrentScreenBlocksProp({
        [blockName]: {
          visibility: function (vis) {
            if ("hidden" != vis) {
              return "hidden";
            }
          },
        },
      });
    },
    //--------------------------------------
    // @params scales: {[blockName]: whr}
    OnComBlockScale(scales = {}) {
      //console.log("OnComBlockScale", scales);
      this.myBlockScales = _.assign({}, this.myBlockScales, scales);

      // 更新所有的相关块的宽高比例
      let data = {};
      let blocks = _.get(this.CurrentScreen, "layout.blocks");
      if (_.isArray(blocks)) {
        // 遍历当前屏幕所有的块 ...
        for (let block of blocks) {
          let whr = scales[block.name];
          if (whr > 0) {
            let { width, height } = block;
            // 比较宽，采用宽度
            if (width > height) {
              height = width / whr;
            }
            // 否则用高度
            else {
              width = height * whr;
            }
            if (!isNaN(width) && !isNaN(height)) {
              data[block.name] = { width, height };
            }
          }
        }
        // 重新调整改变
        this.updateCurrentScreenBlocksProp(data);
      }
    },
    //--------------------------------------
    // @params rsz: {[blockName]: true|"auto"}
    OnComBlockResizable(rsz = {}) {
      if (!_.isMatch(this.myBlockResizable, rsz)) {
        this.myBlockResizable = _.assign({}, this.myBlockResizable, rsz);

        //console.log("OnComBlockResizable", rsz)

        // Update all block
        let screens = this.eachCurrentScreenBlock((block) => {
          let com = this.myDataSchema[block.name];
          let resizable = rsz[block.name];
          // Resizable: auto
          if ("auto" == resizable) {
            delete block.width;
            delete block.height;
          }
          // Resizable: ew-resize
          else if ("ew-resize" == resizable) {
            delete block.height;
          }
          // Resizable: ns-resize
          else if ("ns-resize" == resizable) {
            delete block.width;
          }
          // Resizable: ALL
          else {
            let setup = _.get(this.hmakerComSetups, com.comType);
            let mea = _.defaults({}, setup.measure, {
              width: 180,
              height: 100,
            });
            block.width = Ti.Util.fallbackNil(block.width, mea.width);
            block.height = Ti.Util.fallbackNil(block.height, mea.height);
          }
        });

        // Update current block name
        this.notifyChange({ screens });
      }
    },
    //--------------------------------------
    async OnSelectBlock({ name, checkedNames, shift } = {}) {
      //console.log("OnSelectBlock", { name, shift })
      let blockName = name;
      //.........................................
      // 比例
      //.........................................
      // 清空固定比例
      if (!blockName) {
        this.myCurrentBlockForceRatio = false;
      }
      // 获取控件信息，以便重新获得固定比例
      let com = _.get(this.myDataSchema, blockName);
      if (com && com.comType) {
        com = await this.loadComSetup(com.comType);
        this.myCurrentBlockForceRatio = com.forceRatio || false;
      }
      //.........................................
      // 选中
      //.........................................
      // 直接选中
      if (!_.isUndefined(checkedNames)) {
        this.myCheckedBlockNames = checkedNames
      }
      // 自动选中
      else {
        // 自动选中: 标记
        if (blockName) {
          // 多选模式
          if (shift) {
            this.myCheckedBlockNames = _.uniq(_.concat(this.myCheckedBlockNames, blockName))
          }
          // 单选模式
          else {
            this.myCheckedBlockNames = [blockName]
          }
          this.myCheckedBlockNames = _.uniq(_.concat(this.myCheckedBlockNames, blockName))
        }
        // 自动选中: 取消
        else {
          if (!shift) {
            this.myCheckedBlockNames = []
          }
        }
      }
      //.........................................
      // 当前
      //.........................................
      this.myCurrentBlockName = blockName;
    },
    //--------------------------------------
    OnSelectScreen(screenIndex) {
      this.myCurrentScreenIndex = screenIndex;
    },
    //--------------------------------------
    OnDeviceChange(dev) {
      let lvgl = this.getLvglData();
      lvgl.device = _.assign({}, lvgl.device, dev);
      this.notifyChange(lvgl);
    },
    //--------------------------------------
    OnCurrentScreenNameChange(newName) {
      newName = _.trim(newName);
      // Guard
      if (!this.isValidScreenName(newName)) {
        return;
      }
      let sI = this.findScreenIndexByName(newName);
      if (sI >= 0 && sI != this.myCurrentScreenIndex) {
        Ti.Toast.Open(
          `这个屏幕名称【${newName}】已经被使用了！`,
          "warn",
          "right"
        );
        return;
      }
      // 直接修改当前Screen的名称
      let lvgl = this.getLvglData();
      lvgl.screens[this.myCurrentScreenIndex].name = newName;
      this.notifyChange(lvgl);
    },
    //--------------------------------------
    OnBlockNameChange({ newVal, oldVal } = {}) {
      console.log("OnBlockNameChange", { newVal, oldVal });
      let sI = this.myCurrentScreenIndex;
      if (
        newVal &&
        oldVal &&
        newVal != oldVal &&
        _.isArray(this.myDataScreens) &&
        sI >= 0 &&
        sI < this.myDataScreens.length
      ) {
        // Update block in screen
        let screens = _.cloneDeep(this.myDataScreens);
        let screen = screens[sI];
        screen.layout = screen.layout || {};
        screen.layout.blocks = screen.layout.blocks || [];

        // Forbid uniqe name
        if (!this.isValidtBlockName(newVal, false)) {
          return;
        }

        // Replace the block
        for (let block of screen.layout.blocks) {
          if (block.name == oldVal) {
            block.name = newVal;
            block.body = newVal;
          }
        }

        // Update schema
        let conf = _.get(this.myDataSchema, oldVal);
        let schema = _.omit(this.myDataSchema, oldVal);
        schema[newVal] = conf;

        // Update resources
        let resources = _.cloneDeep(this.myDataResources);
        _.forEach(resources, (rs) => {
          rs.names = _.map(rs.names, (nm) => {
            return oldVal == nm ? newVal : nm;
          });
        });

        // Update current block name
        this.myCurrentBlockName = newVal;

        // Remove resiable
        this.myBlockResizable = _.omit(this.myBlockResizable, oldVal);

        this.notifyChange({ screens, schema, resources }, true);
      }
    },
    //--------------------------------------
    OnBlockPropChange({ name, value } = {}) {
      //console.log("OnBlockPropChange", { name, value })
      // 如果改变组件的宽高，注意等比问题
      let props = { [name]: value };
      // if (this.CurrentBlockScale > 0) {
      //   let whr = this.CurrentBlockScale;
      //   // 宽度改变，同时联动高度
      //   if ("width" == name) {
      //     props.height = value / whr;
      //   }
      //   // 高度改变，同时联动宽度
      //   else if ("height" == name) {
      //     props.width = value * whr;
      //   }
      // }
      this.OnBlockPropDataChange(props);
    },
    //--------------------------------------
    OnBlockPropDataChange(props = {}) {
      //console.log("OnBlockPropChange", props)
      if (this.CurrentBlockScale > 0) {
        let whr = this.CurrentBlockScale;
        // 宽度改变，同时联动高度
        if (!Ti.Util.isNil(props.width)) {
          props.height = props.width / whr;
        }
        // 高度改变，同时联动宽度
        if (!Ti.Util.isNil(props.height)) {
          props.width = props.height * whr;
        }
      }
      this.updateCurrentBlockProp(props);
    },
    //--------------------------------------
    OnCurrentComConfFieldChange({ name, value } = {}) {
      //console.log("OnComConfChange", { name, value })
      this.updateCurrentComConf({
        [name]: value,
      });
    },
    //--------------------------------------
    OnComConfChange(data = {}) {
      this.updateComConf(data);
    },
    //--------------------------------------
    cloneMyDataScreens() {
      let screens = _.cloneDeep(this.myDataScreens);
      let screen = screens[this.myCurrentScreenIndex];
      screen.layout = screen.layout || {};
      screen.layout.blocks = screen.layout.blocks || [];
      return screens;
    },
    //--------------------------------------
    addNewScreen(screenName) {
      screenName = _.trim(screenName);
      // Guard
      if (!this.isValidScreenName(screenName, { quiet: false, unique: true })) {
        return;
      }

      let { screens } = this.getLvglData() || [];

      // Add new screen object
      screens.push({
        name: screenName,
        layout: {
          type: "free",
          blocks: [],
        },
      });
      this.myCurrentScreenIndex = screens.length - 1;
      this.notifyChange({ screens });
      Ti.Viewport.notifyResize();
    },
    //--------------------------------------
    removeScreen(screenIndex) {
      // Get all block name
      let blockNames = {};
      let screen = _.nth(this.myDataScreens, screenIndex);
      let screenBlocks = _.get(screen, "layout.blocks");
      const __joinBlockNames = ({ name, blocks }) => {
        if (name) {
          blockNames[name] = true;
        }
        _.forEach(blocks, __joinBlockNames);
      };
      _.forEach(screenBlocks, __joinBlockNames);
      // Remove schema
      let schema = {};
      _.forEach(this.myDataSchema, (val, key) => {
        if (!blockNames[key]) {
          schema[key] = val;
        }
      });
      // Remove screen
      let screens = _.filter(this.myDataScreens, (screen, index) => {
        return index != screenIndex;
      });
      // Update screen index and notify
      let sI = _.clamp(this.myCurrentScreenIndex, 0, screens.length - 1);
      this.myCurrentScreenIndex = sI;
      this.notifyChange({ screens, schema }, true);
      Ti.Viewport.notifyResize();
    },
    //--------------------------------------
    addBlockToScreen(block) {
      // Guard
      if (_.isEmpty(block) || !this.hasCurrentScreen) {
        return;
      }

      // Assign block name
      this.autoAssignBlockName(block);

      // Split block/schema
      let blockSchema = _.pick(block, "comType", "comConf");
      if (!blockSchema.comType) {
        console.error("Block waithout comType", block);
        return;
      }
      block = _.omit(block, "comType", "comConf");
      block.body = block.name;

      // Block default measure
      _.defaults(block, {
        x: 10,
        y: 10,
      });

      if (!/^(auto|ew-resize)$/.test(block.defaultResizable)) {
        _.defaults(block, { width: 180 });
      }

      if (!/^(auto|ns-resize)$/.test(block.defaultResizable)) {
        _.defaults(block, { height: 100 });
      }

      // Add block in screen
      let screens = this.cloneMyDataScreens();
      let screen = screens[this.myCurrentScreenIndex];

      // Check screen layout
      if (!_.isArray(_.get(screen, "layout.blocks"))) {
        _.set(screen, "layout.blocks", []);
      }

      // Append and notify
      screen.layout.blocks.push(block);
      let schema = _.assign({}, this.myDataSchema, {
        [block.name]: blockSchema,
      });
      this.myCurrentBlockName = block.name;
      this.notifyChange({ screens, schema });
    },
    //--------------------------------------
    moveCurrentBlockTo(direction = "prev") {
      // Guard: must has current block
      if (!this.myCurrentBlockName) {
        return Ti.Toast.Open("请先选择一个要移动的控件!");
      }
      //console.log("moveCurrentBlockTo", direction)
      // Add block in screen
      let screens = this.cloneMyDataScreens();
      let screen = screens[this.myCurrentScreenIndex];

      // Get current block
      let { index, axis, atTop } = this.CurrentBlock;
      let pBlock = this.findBlockByAxis(screen.layout, axis);

      // Move block in same leval
      if (/^(head|tail|next|prev)$/.test(direction)) {
        let blocks = Ti.Util.moveArrayElementBy(
          pBlock.blocks,
          (b) => {
            return b.name == this.myCurrentBlockName;
          },
          direction
        );
        pBlock.blocks = blocks;
      }
      // Move block cross hierarchy: outside
      else if ("outside" == direction) {
        if (axis.length > 0) {
          let anBlock = this.findBlockByAxis(
            screen.layout,
            axis.slice(0, axis.length - 1)
          );
          let b = pBlock.blocks[index];
          // Remove from current
          pBlock.blocks.splice(index, 1);
          // Insert to nextsibling of parent
          let pIndex = this.ScreenBlockDict[pBlock.name].index;
          anBlock.blocks.splice(pIndex, 0, b);
        }
      }
      // Move block cross hierarchy: inside
      else if ("inside" == direction) {
        if (!atTop) {
          // Get prev block
          let b = pBlock.blocks[index];
          let prev = pBlock.blocks[index + 1];
          // Remove from current
          pBlock.blocks.splice(index, 1);
          // Join the prev
          if (!_.isArray(prev.blocks)) {
            prev.blocks = [];
          }
          prev.blocks.push(b);
        }
      }
      // Invalide direction
      else {
        throw `Invalid direction (${direction}) when moveCurrentBlockTo`;
      }

      // Append and notify
      this.notifyChange({ screens });
    },
    //--------------------------------------
    removeBlockFromScreen(blockNameToDel) {
      // Guard
      if (!blockNameToDel || !this.hasCurrentScreen) {
        return;
      }
      // Get the block info, specially, the axis
      let cb = _.get(this.ScreenBlockDict, blockNameToDel);
      if (!cb) {
        console.warn(`Fail to found block [${blockNameToDel}]`);
        return;
      }
      //console.log("removeBlockFromScreen", blockNameToDel);

      // Remove block in screen
      let screens = this.cloneMyDataScreens();
      let screen = screens[this.myCurrentScreenIndex];

      // Get the parent blockOrScreen for current
      let delBlockNames = {};
      let block = this.findBlockByAxis(screen.layout, cb.axis);
      if (block && block.blocks) {
        block.blocks = _.filter(block.blocks, (b) => {
          if (b.name == blockNameToDel) {
            delBlockNames[b.name] = true;
            this.walkBlock(b, ({ name }) => {
              delBlockNames[name] = true;
            });
            return false;
          }
          return true;
        });
      }

      // Remove from com signup
      _.forEach(delBlockNames, (_, blockName) => {
        delete this.myComDict[blockName]
      })

      // Remove from schema
      let schema = {};
      _.forEach(this.myDataSchema, (val, key) => {
        if (!delBlockNames[key]) {
          schema[key] = val;
        }
      });

      // Remove from resource
      let resources = {};
      _.forEach(this.myDataResources, (rs, key) => {
        _.remove(rs.names, (nm) => delBlockNames[nm]);
        if (!_.isEmpty(rs.names)) {
          resources[key] = rs;
        }
      });

      // Remove resizable
      this.myBlockResizable = _.omitBy(
        this.myBlockResizable,
        (_, key) => delBlockNames[key]
      );

      // Append and notify
      this.myCurrentBlockName = undefined;
      this.notifyChange({ screens, schema, resources }, true);
    },
    //--------------------------------------
    updateCurrentBlockProp(prop = {}) {
      //console.log("updateCurrentBlockProp", prop)
      // Guard
      if (!this.myCurrentBlockName) {
        return;
      }
      let data = { [this.myCurrentBlockName]: prop };
      this.updateCurrentScreenBlocksProp(data);
    },
    //--------------------------------------
    /**
     * 一次更新一个块的多个属性
     *
     * @param {Object} data : '{blockName: {x,y,width,height} ...}'
     */
    updateCurrentScreenBlocksProp(data = {}) {
      //console.log("updateBlockProp", data)
      // Guard
      let screens = this.createUpdateScreenBlocksProp(data);
      this.notifyChange({ screens }, true);
    },
    //--------------------------------------
    createUpdateScreenBlocksProp(data = {}) {
      if (_.isEmpty(data)) {
        return;
      }
      let screens = this.eachCurrentScreenBlock((block) => {
        // 得到要更新的块属性
        let bd = data[block.name];
        if (!_.isEmpty(bd)) {
          // 准备更新块
          let bd2 = {};
          _.forEach(bd, (v, k) => {
            // 防守: 未定义
            if (_.isUndefined(v)) {
              return;
            }
            // 计算属性值
            if (_.isFunction(v)) {
              // 1. 获取原先属性
              let oldV = block[k];
              // 2. 计算
              v = v(oldV, k, block);
            }

            // x/y/width/height 需要四舍五入
            if (/^(x|y|width|height)$/.test(k)) {
              v = Math.round(v);
              if (isNaN(v)) {
                return;
              }
            }
            // 设置值
            if (!_.isUndefined(v)) {
              bd2[k] = v;
            }
            // 删除值: 某些时候，计算属性返回 undefined, 则删除它
            else {
              delete block[k];
            }
          });
          _.assign(block, bd2);
        }
      });
      return screens;
    },
    //--------------------------------------
    eachCurrentScreenBlock(callback = (b) => b) {
      // Update block in screen
      let screens = this.cloneMyDataScreens();
      let screen = screens[this.myCurrentScreenIndex];

      // Check screen layout
      if (!_.isArray(_.get(screen, "layout.blocks"))) {
        _.set(screen, "layout.blocks", []);
      }

      // 定义递归函数
      const loop_into = function (blocks) {
        if (_.isEmpty(blocks) || !_.isArray(blocks)) {
          return
        }
        for (let block of blocks) {
          callback(block);
          // 递归
          loop_into(block.blocks)
        }
      }

      // 调用
      loop_into(screen.layout.blocks)

      // 搞定
      return screens;
    },
    //--------------------------------------
    updateCurrentComConf(data = {}) {
      // Guard
      if (!this.myCurrentBlockName) {
        return;
      }
      // Update block in screen
      let schema = _.cloneDeep(this.myDataSchema);
      let curCom = _.get(schema, this.myCurrentBlockName);
      curCom.comConf = curCom.comConf || {};

      // Update the block
      _.forEach(data, (value, name) => {
        _.set(curCom.comConf, name, value);
      });

      // Update current block name
      this.notifyChange({ schema }, true);
    },
    //--------------------------------------
    updateComConf(data = {}) {
      // Guard
      if (_.isEmpty(data)) {
        return;
      }
      // Update block
      let schema = _.cloneDeep(this.myDataSchema);
      _.forEach(data, (conf, blockName) => {
        let taComConf = schema[blockName];
        if (!taComConf) {
          taComConf = {};
          schema[blockName] = taComConf;
        }
        _.forEach(conf, (value, name) => {
          _.set(taComConf, name, value);
        });
      });

      // Update current block name
      this.notifyChange({ schema }, true);
    },
    //--------------------------------------
    getLvglData() {
      return _.cloneDeep({
        device: this.myDataDevice,
        screens: this.myDataScreens,
        schema: this.myDataSchema,
        resources: this.myDataResources,
      });
    },
    //--------------------------------------
    findScreenIndexByBlock(blockName) {
      for (let i = 0; i < this.myDataScreens.length; i++) {
        if (this.isBlockInScreen(blockName, i)) {
          return i
        }
      }
      return -1
    },
    //--------------------------------------
    isBlockInScreen(blockName, screenIndex) {
      let screen = _.nth(this.myDataScreens, screenIndex);
      if (!screen || !screen.layout) {
        return false
      }
      const isBlockIn = (blocks = [], blockName) => {
        for (let block of blocks) {
          if (block.name == blockName) {
            return true
          }
          if (isBlockIn(block.blocks, blockName)) {
            return true
          }
        }
        return false
      }
      return isBlockIn(screen.layout.blocks, blockName)
    },
    //--------------------------------------
    notifyChange({ device, screens, schema, resources }, cleanResource = false) {
      let lvgl = this.getLvglData();
      if (device) {
        lvgl.device = device;
      }
      if (screens) {
        lvgl.screens = screens;
      }
      if (schema) {
        lvgl.schema = schema;
      }
      if (resources) {
        lvgl.resources = resources;
      }

      // IDE 未适配修改: 去掉值为 null 与 undefined 的内容
      this.deleteEmptyProperty(lvgl);

      // IDE 未适配修改: 调整 button 中的 label 属性
      this.modifyButtonLabelProp(lvgl);

      // IDE 未适配修改: 老版本 button 的 state 属性更新
      this.modifyButtonStateProp(lvgl);

      // IDE 未适配修改: 老版本 checkbox 的两个属性同时用，都取消掉
      this.modifyCheckboxCheckedAndDisabledProp(lvgl);

      // 清理 lvgl block 的临时属性
      for (let screen of lvgl.screens) {
        this.walkBlock(screen.layout, (b) => {
          delete b.axis;
          delete b.index;
          delete b.depth;
          delete b.isFirst;
          delete b.isLast;
          delete b.atTop;
          delete b.atBottom;
          delete b.defaultResizable;
        });
      }

      let content = JSON.stringify(lvgl, null, "  ");

      //console.log("notify-lvgl:\n" + content);
      // 通知变动
      this.$notify("change", content);
      // Watch value
      this.FnValueWatcher(lvgl);

      // 清理悬垂的 resources 记录
      if (cleanResource) {
        _.delay(() => {
          this.doCleanUnusedResource(lvgl.resources)
        })
      }
    },
    //--------------------------------------
    updateCurrentBlockMeasure(mea = {}) {
      this.myCurrentBlockMeasure = mea;
    },
    //--------------------------------------
    async evalMyContentData(lvgl = this.ContentData) {
      // Load schema
      let device = _.get(lvgl, "device") || {
        width: 640,
        height: 480,
      };
      let screens = _.get(lvgl, "screens") || [];
      let schema = _.get(lvgl, "schema") || {};
      let resources = _.get(lvgl, "resources") || {};

      // Preload com defined in schema
      for (let blockName of _.keys(schema)) {
        let com = schema[blockName];
        await this.loadComSetup(com.comType);
      }

      // Update properties
      this.myDataDevice = device;
      this.myDataScreens = screens;
      this.myDataSchema = schema;
      this.myDataResources = resources;
      this.myCurrentScreenIndex = _.clamp(
        this.myCurrentScreenIndex,
        0,
        this.myDataScreens.length
      );
    },
    //--------------------------------------
    autoAssignBlockName(block = {}) {
      if (!Ti.Util.isNil(block.name) && this.isValidtBlockName(block.name)) {
        return block;
      }
      let prefix = block.comType || "Block";
      let n = 1;
      let name = [prefix, n].join("");
      while (this.ScreenBlockDict[name]) {
        n++;
        name = [prefix, n].join("");
      }
      block.name = name;
    },
    //--------------------------------------
    walkBlock(
      { blocks } = {},
      iteretee = _.identity,
      { includeSelf = false } = {}
    ) {
      let axis = [];
      if (!_.isEmpty(blocks)) {
        for (let index = 0; index < blocks.length; index++) {
          let b = blocks[index];
          iteretee(b, { axis, index });
          if (b.blocks) {
            this.walkBlock(b, iteretee);
          }
        }
      }
    },
    //--------------------------------------
    findBlockByAxis(blockOrLayout, axis = [], off = 0) {
      if (!blockOrLayout || off >= axis.length) {
        return blockOrLayout;
      }
      if (!_.isEmpty(blockOrLayout.blocks)) {
        let name = axis[off];
        let block = _.find(blockOrLayout.blocks, (b) => b.name == name);
        return this.findBlockByAxis(block, axis, off + 1);
      }
    },
    //--------------------------------------
    findScreenIndexByName(screenName) {
      let sn = _.toLower(screenName);
      for (let i = 0; i < this.myDataScreens.length; i++) {
        let screen = this.myDataScreens[i];
        if (screen && _.toLower(screen.name) == sn) {
          return i;
        }
      }
      return -1;
    },
    //--------------------------------------
    isValidScreenName(screenName, { quiet = false, unique = false } = {}) {
      if (!screenName) {
        if (!quiet) Ti.Toast.Open("屏幕名称不能为空!", "warn", "right");
        return false;
      }
      // 检查屏幕名称
      if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(screenName)) {
        if (!quiet)
          Ti.Toast.Open(
            "屏幕名称只能是英文数字或者下划线，并且不能以数字开头",
            "warn",
            "right"
          );
        return false;
      }
      // Unique screen name
      if (unique) {
        let sn = _.toLower(screenName);
        for (let screen of this.myDataScreens) {
          if (_.toLower(screen.name) == sn) {
            if (!quiet)
              Ti.Toast.Open(
                "屏幕名称已经被使用：" + screenName,
                "warn",
                "right"
              );
            return false;
          }
        }
      }
      return true;
    },
    //--------------------------------------
    isValidtBlockName(name, quiet = true) {
      if (!name) {
        if (!quiet) Ti.Toast.Open("对象名称不能为空!", "warn", "right");
        return false;
      }
      // Check Name
      if (!/^[a-zA-Z0-9_]+$/.test(name)) {
        if (!quiet)
          Ti.Toast.Open("对象名称只能是英文数字或者下划线", "warn", "right");
        return false;
      }
      let block = this.ScreenBlockDict[name];
      if (block) {
        if (!quiet) {
          Ti.Toast.Open("对象名称已经被使用：" + name, "warn", "right");
        }
        return false;
      }
      return true;
    },
    //--------------------------------------
    // 清理对象中的空属性
    deleteEmptyProperty(object) {
      for (var prop in object) {
        var value = object[prop];
        if (typeof value === "object" && value !== null) {
          this.deleteEmptyProperty(value);
        } else {
          if (value === null || value === undefined || Number.isNaN(value)) {
            delete object[prop];
          }
        }
      }
    },
    // 将 button 中的 label 相关内容放到 comConf 中
    modifyButtonLabelProp(lvgl) {
      let schema = lvgl.schema || {};
      for (let widgetName in schema) {
        let widget = schema[widgetName];
        if (widget.comType == "LvglButton") {
          let comConf = widget.comConf;
          let virtualLabel = {
            comType: "LvglLabel",
            comConf: {
              text: "",
              defaultStatus: {
                mainPart: {
                  text: {},
                },
              },
            },
          };
          comConf.virtualLabel = virtualLabel;
          // 属性
          virtualLabel.comConf.text = comConf.text || "";
          // 样式
          virtualLabel.comConf.defaultStatus.mainPart.text =
            comConf.defaultStatus.mainPart.text || {};
        }
      }
    },
    // 老版本中 BTN_STATE_DEFAULT 改成 BTN_STATE_RELEASED
    modifyButtonStateProp(lvgl) {
      let schema = lvgl.schema || {};
      for (let widgetName in schema) {
        let widget = schema[widgetName];
        if (widget.comType == "LvglButton") {
          let comConf = widget.comConf;
          if (comConf.state && comConf.state == "BTN_STATE_DEFAULT") {
            comConf.state = "BTN_STATE_RELEASED";
          }
        }
      }
    },
    // 老版本中同时开启 checked 和 disabled
    modifyCheckboxCheckedAndDisabledProp(lvgl) {
      let schema = lvgl.schema || {};
      for (let widgetName in schema) {
        let widget = schema[widgetName];
        if (widget.comType == "LvglCheckbox") {
          let comConf = widget.comConf;
          if (comConf.checked === true && comConf.disabled === true) {
            comConf.checked = false;
            comConf.disabled = false;
          }
        }
      }
    },
    //--------------------------------------
    signupCom(blockName, $com) {
      this.myComDict[blockName] = $com
    },
    //--------------------------------------
    saveLocalSetting() {
      if (this.keepSettingTo) {
        let setup = {
          showBlockOutline: this.showBlockOutline,
          showIndicateIcon: this.showIndicateIcon,
          showBlockType: this.showBlockType,
          showBlockName: this.showBlockName,
          showScreenRotation: this.showScreenRotation,
        };
        Ti.Storage.local.setObject(this.keepSettingTo, setup);
      }
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  watch: {
    ContentData: {
      handler: "evalMyContentData",
      immediate: true,
    },
    // 当用户疯狂点击控件切换（30ms以内），会导致 myCurrentBlockMeasure 不能被及时释放
    // 用这个监听器临时搞一下，应该就能避免这个问题了
    myCurrentBlockName: function (newVal, oldVal) {
      if (newVal && newVal != oldVal) {
        this.myCurrentBlockMeasure = {};
      }
    },
  },
  //////////////////////////////////////////
  created: function () {
    // FIXME: 拖动过快时会导致 x,y 属性不更新
    this.debounceUpdateCurrentBlockMeasure = _.debounce((mea) => {
      this.updateCurrentBlockMeasure(mea);
    }, 30);
    // Local from local setting
    if (this.keepSettingTo) {
      let setup = Ti.Storage.local.getObject(this.keepSettingTo);
      //console.log(setup)
      this.showBlockOutline = Ti.Util.fallback(setup.showBlockOutline, false);
      this.showIndicateIcon = Ti.Util.fallback(setup.showIndicateIcon, false);
      this.showBlockType = Ti.Util.fallback(setup.showBlockType, false);
      this.showBlockName = Ti.Util.fallback(setup.showBlockName, false);
      this.showScreenRotation = Ti.Util.fallback(
        setup.showScreenRotation,
        false
      );
    }
  },
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-style-margin.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/style/margin/lvgl-maker-style-margin.mjs'] = (function(){
////////////////////////////////////////////////////////
const _M = {
  //////////////////////////////////////////////////////
  props: {
    //-----------------------------------
    // Data
    //-----------------------------------
    "value": {
      type: Object
    }
  },
  //////////////////////////////////////////////////////
  computed: {
    //--------------------------------------------------
    StyleForm() {
      return {
        spacing: "comfy",
        fields: [
          {
            "title": "上",
            "name": "top",
            "type": "Integer",
            "comType": "TiInputNum"
          },
          {
            "title": "下",
            "name": "bottom",
            "type": "Integer",
            "comType": "TiInputNum"
          },
          {
            "title": "左",
            "name": "left",
            "type": "Integer",
            "comType": "TiInputNum"
          },
          {
            "title": "右",
            "name": "right",
            "type": "Integer",
            "comType": "TiInputNum"
          },
        ]
      }
    }
    //--------------------------------------------------
  }
  //////////////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'page-footer.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/page/footer/page-footer.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props : {
    "logo": {
      type: String,
      default: "img/footer-logo.png"
    }
  },
  //////////////////////////////////////////
  computed : {
    //--------------------------------------
    TopClass() {
      return this.getTopClass()
    },
    //--------------------------------------
    LogoSrc() {
      return `${this.base}${this.logo}`
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods : {
    //--------------------------------------
    //--------------------------------------
  }
  //////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-form-animat-val.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/form/animat-val/lvgl-maker-form-animat-val.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props: {
    "value": {
      type: [Array, Number]
    },
    "range": {
      type: Array,
      default: () => [0, 100]
    }
  },
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    ValObj() {
      if (_.isNumber(this.value)) {
        return { val: this.value, animat: false }
      }
      if (_.isArray(this.value)) {
        return {
          val: _.nth(this.value, 0),
          animat: "ANIM_ON" == _.nth(this.value, 1)
        }
      }
      return { val: this.range[0], animat: false }
    },
    //--------------------------------------
    InputVal() {
      return this.ValObj.val
    },
    //--------------------------------------
    InputSuffixText() {
      if (this.ValObj.animat) {
        return "动画开启"
      }
      return "动画关闭"
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    OnInputChange(v) {
      // 转换值，并防守
      let ms = parseInt(v)
      if (isNaN(ms)) {
        return
      }
      let [min, max] = this.range
      ms = _.clamp(ms, min, max)
      let vs = [ms]
      vs.push(this.ValObj.animat ? "ANIM_ON" : "ANIM_OFF");
      this.$notify("change", vs)
    },
    //--------------------------------------
    OnClickSuffixText() {
      let ms = Ti.Util.fallback(this.ValObj.val, this.range[0])
      let vs = [ms]
      vs.push(this.ValObj.animat ? "ANIM_OFF" : "ANIM_ON");
      this.$notify("change", vs)
    }
    //--------------------------------------
  }
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'build-result.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/buildshop/result/build-result.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////////////
  props: {
    "data": {
      type: Object
    },
    "buildLog": {
      type: Object
    },
    "currentBuild": {
      type: Object
    },
    "currentBuildSize": {
      type: Number,
      default: 0
    },
    "currentMaxBuildSize": {
      type: Number,
      default: 0
    },
    "status": {
      type: Object
    }
  },
  ///////////////////////////////////////////////////////
  computed: {
    //---------------------------------------------------
    hasData() {
      return !_.isEmpty(this.data)
    },
    //---------------------------------------------------
    hasBuildSize() {
      return this.currentBuildSize > 0
    },
    //---------------------------------------------------
    BuildSizeText() {
      return Ti.S.sizeText(this.currentBuildSize)
    },
    //---------------------------------------------------
    MaxBuildSizeText() {
      return Ti.S.sizeText(this.currentMaxBuildSize)
    },
    //---------------------------------------------------
    BuildSizeRatio() {
      return this.currentBuildSize/ this.currentMaxBuildSize
    },
    //---------------------------------------------------
    isBuildOverSize() {
      return this.BuildSizeRatio >= 1;
    },
    //---------------------------------------------------
    BuildSizeBarClass() {
      if(this.isBuildOverSize) {
        return "is-over-size"
      }
    },
    //---------------------------------------------------
    BuildSizeBarInnerStyle() {
      return {
        width: Ti.S.toPercent(this.BuildSizeRatio)
      }
    },
    //---------------------------------------------------
    hasBuildLog() {
      return !_.isEmpty(this.buildLog)
    },
    //---------------------------------------------------
    BuildStartAt() {
      let startAt = _.get(this.currentBuild, "start_at")
      if (startAt) {
        return Ti.DateTime.format(startAt)
      }
    },
    //---------------------------------------------------
    BuildDoneAt() {
      let doneAt = _.get(this.currentBuild, "done_at")
      if (doneAt) {
        return Ti.DateTime.format(doneAt)
      }
    },
    //---------------------------------------------------
    BuildStatus() {
      return _.get(this.currentBuild, "build_stat") || 0
    },
    //---------------------------------------------------
    BuildStatusText() {
      return ({
        "0": "编辑中",
        "1": "排队中",
        "2": "编译中",
        "10": "编译成功",
        "20": "编译失败"
      })[this.BuildStatus]
    },
    //---------------------------------------------------
    BuildDestDownloadUrl() {
      if (this.currentBuild && this.hasData) {
        let downName = this.currentBuild.title || this.currentBuild.nm || "dest.zip"
        if (!/\.zip$/.test(downName)) {
          downName += ".zip"
        }
        let apiUrl = Ti.Util.appendPath(this.apiBase, "down")
        return `${apiUrl}?f=id:${this.data.id}&dwnm=${downName}`
      }
    },
    //---------------------------------------------------
    BuildLogDownloadUrl() {
      if (this.currentBuild && this.hasBuildLog) {
        let downName = this.currentBuild.title || this.currentBuild.nm || "build.log"
        if (!/build\.log$/.test(downName)) {
          downName += ".build.log"
        }
        let apiUrl = Ti.Util.appendPath(this.apiBase, "down")
        return `${apiUrl}?f=id:${this.buildLog.id}&dwnm=${downName}`
      }
    },
    //---------------------------------------------------
    ActionBtnSetup() {
      let st = this.BuildStatus
      let refreshBtn = {
        icon: "fas-sync",
        text: "刷新结果",
        eventName: "reload:build:dest"
      }
      // 编辑中 -> 排队中
      if (0 === st) {
        return [
          this.genStatusAction(1, "far-check-circle", "开始编译")
        ]
      }
      // 准备就绪
      if (1 === st) {
        return [
          this.genStatusAction(0, "far-edit", "重新编辑"),
          refreshBtn
        ]
      }
      // 构建中
      if (2 === st) {
        return [refreshBtn]
      }
      // 构建成功
      if (10 === st) {
        return [
          this.genStatusAction(0, "far-edit", "重新编辑")
        ]
      }
      // 构建失败
      if (20 === st) {
        return [
          this.genStatusAction(0, "far-edit", "重新编辑")
        ]
      }
    }
    //---------------------------------------------------
  },
  ///////////////////////////////////////////////////////
  methods: {
    //---------------------------------------------------
    genStatusAction(targetStatus, icon, text) {
      return {
        icon, text,
        eventName: "update:build:status",
        payload: targetStatus
      }
    }
    //---------------------------------------------------
  }
  ///////////////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-stage.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/stage/lvgl-maker-stage.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  inject: ["$maker"],
  //////////////////////////////////////////
  provide: function () {
    return {
      $stage: this,
    };
  },
  //////////////////////////////////////////
  data: () => ({
    myMainRect: undefined,
    myZoomScale: undefined,
    myX: undefined,
    myY: undefined,
    myWidth: undefined,
    myHeight: undefined,

    showPreviewButton: false,
  }),
  //////////////////////////////////////////
  props: {
    lvglResources: {
      type: Object,
      default: () => ({}),
    },
    // 当 $maker.myCurrentBlockForceRatio 开启时，
    // 本选项用来提供当前块真实的宽高比。
    // 0 表示关闭等比推拽缩放
    blockScale: {
      type: Number,
      default: 0,
    },
    blockResizable: {
      type: Object,
      default: () => ({}),
    },
    showScreenRotation: {
      type: Boolean,
      default: true,
    },
    showBlockOutline: {
      type: Boolean,
      default: true,
    },
    showIndicateIcon: {
      type: Boolean,
      default: false,
    },
    showBlockType: {
      type: Boolean,
      default: false,
    },
    showBlockName: {
      type: Boolean,
      default: false,
    },
    keyboardMoveStep: {
      type: Number,
      default: 5,
    },
    showOutlinePanel: {
      type: Boolean,
      default: false,
    },
  },
  //////////////////////////////////////////
  computed: {
    zoomVal() {
      let val = this.myZoomScale ? this.myZoomScale * 100 : 0;
      return val.toFixed(0);
    },
    //--------------------------------------
    TopClass() {
      return this.getTopClass({
        "is-show-block-outline": this.showBlockOutline,
        "is-show-indicate-icon": this.showIndicateIcon,
        "is-show-block-type": this.showBlockType,
        "is-show-block-name": this.showBlockName,

        "is-hide-block-outline": !this.showBlockOutline,
        "is-hide-indicate-icon": !this.showIndicateIcon,
        "is-hide-block-type": !this.showBlockType,
        "is-hide-block-name": !this.showBlockName,

        "is-show-outline-panel": this.showOutlinePanel,
        "no-show-outline-panel": !this.showOutlinePanel,
      });
    },
    //--------------------------------------
    StageComCheckTip() {
      let names = this.checkedBlockNames
      if (!_.isEmpty(names)) {
        let len = names.length;
        let n = Math.min(2, len)
        let nms = names.slice(0, n)
        if (len > 2) {
          return `${nms.join(",")}等${len}控件`
        }
        return nms.join(",")
      }
    },
    //--------------------------------------
    StageInDragging() {
      return this.$maker.stageInDragging;
    },
    //--------------------------------------
    LvglScreenNames() {
      let list = [];
      _.forEach(this.LvglScreens, (screen, index) => {
        let current = index == this.currentScreenIndex;
        list.push({
          current,
          className: {
            "is-current": current,
            "no-current": !current,
          },
          icon: "zmdi-tablet-android",
          text: screen.name,
          value: index,
        });
      });
      return list;
    },
    //--------------------------------------
    ViewportRotation() {
      let devRotationNm = _.get(this.device, "rotation") || "DISP_ROT_NONE";
      if (!devRotationNm.includes("ROT_NONE")) {
        return devRotationNm.replace("DISP_ROT_", "");
      }
      return "0";
    },
    //--------------------------------------
    ViewportStyle() {
      if (!this.myMainRect) return;

      let { width, height } = this.myMainRect;
      let devW = _.get(this.device, "width");
      let devH = _.get(this.device, "height");
      let devBg = _.get(this.device, "bg");
      // 屏幕是否旋转
      let devRotationNm = _.get(this.device, "rotation") || "DISP_ROT_NONE";
      if (!devRotationNm.includes("ROT_NONE")) {
        if (
          devRotationNm.includes("ROT_90") ||
          devRotationNm.includes("ROT_270")
        ) {
          [devW, devH] = [devH, devW];
        }
      }
      let devRect = Ti.Rects.create({ width: devW, height: devH }, "tlwh");
      width = Math.round(width);
      height = Math.round(height);
      devRect.zoomTo({ width, height, round: true });

      this.myZoomScale = devRect.width / devW;
      let css = devRect.toCss({ width, height });

      if (!_.isEmpty(devBg)) {
        this.setCssBackgroundStyle(css, devBg)
      }

      return Ti.Css.toStyle(css);
    },
    //--------------------------------------
    ViewBlockItems() {
      if (!_.isNumber(this.myZoomScale) || !this.LvglCurrentScreen) {
        return [];
      }
      //...............................
      let blocks = _.get(this.LvglCurrentScreen, "layout.blocks");
      blocks = _.cloneDeep(blocks) || [];
      //...............................
      const makeBlock = (block, index, axis = []) => {
        block.axis = axis;
        block.depth = axis.length;
        block.resizable = Ti.Util.fallbackNil(
          this.blockResizable[block.name],
          block.defaultResizable,
          true
        );
        block.isAutoResize = "auto" == block.resizable;
        block.isEWResize =
          "ew-resize" == block.resizable || true === block.resizable;
        block.isNSResize =
          "ns-resize" == block.resizable || true === block.resizable;
        // Count the block display rect
        if (!block.rect) {
          // Reisize: Auto
          block.rect = {
            left: block.x || 0,
            top: block.y || 0,
          };
          // Reisize: ew-resize
          if (block.isEWResize) {
            block.width = Ti.Util.fallbackNil(block.width, 180);
            block.rect.width = block.width;
          }
          // Reisize: ns-resize
          if (block.isNSResize) {
            block.height = Ti.Util.fallbackNil(block.height, 100);
            block.rect.height = block.height;
          }
        }
        let { width, height } = block.rect;
        block.current = block.name == this.currentBlockName;
        block.index = index;
        block.className = {
          "is-current": block.current,
          "is-hidden": "hidden" == block.visibility,
        };

        if (!block.isAutoResize) {
          // block.style.width = `${width * this.myZoomScale}px`;
          // block.style.height = `${height * this.myZoomScale}px`;
          block.width = width;
          block.height = height;
        }
        let com = _.get(this.schema, block.name);
        if (!com) {
          console.warn(`fail to found scheme['${block.name}']`, block);
        }
        if (com && com.comType) {
          let info = _.get(this.LvglComDict, com.comType);
          block.comIcon = Ti.Icons.parseFontIcon(_.get(info, "icon"));
          block.comName = _.get(info, "text");
          block.comType = com.comType;
          block.comConf = com.comConf;
        }
        // 处理子节点
        block.hasChildren = !_.isEmpty(block.blocks);
        if (block.hasChildren) {
          for (let i = 0; i < block.blocks.length; i++) {
            makeBlock(block.blocks[i], i, [...axis, block.name]);
          }
          _.forEach(block.blocks, makeBlock);
        }
      };
      // Covert rect to style
      for (let i = 0; i < blocks.length; i++) {
        makeBlock(blocks[i], i);
      }

      // Done
      return blocks;
    },
    //--------------------------------------
    DragMethods() {
      return {
        //.....................................................
        NW: (ctx) => {
          let { orgX, orgY, orgWidth, orgHeight, offsetX, offsetY } = ctx;
          let orgRight = orgX + orgWidth;
          let orgBottom = orgY + orgHeight;

          let x = Math.round(orgX + offsetX / this.myZoomScale);
          let width = Math.max(orgRight - x, 1);

          let y, height;
          // 等比缩放
          if (this.blockScale > 0) {
            height = width / this.blockScale;
            y = orgBottom - height;
          }
          // 自由缩放
          else {
            y = Math.round(orgY + offsetY / this.myZoomScale);
            height = Math.max(orgBottom - y, 1);
          }
          this.myX = x;
          this.myY = y;
          this.myWidth = width;
          this.myHeight = height;
          this.$maker.debounceUpdateCurrentBlockMeasure({
            x,
            y,
            width,
            height,
          });
        },
        //.....................................................
        NE: (ctx) => {
          let { orgY, orgWidth, orgHeight, offsetX, offsetY } = ctx;
          let orgBottom = orgY + orgHeight;

          let width = Math.round(orgWidth + offsetX / this.myZoomScale);

          let y, height;
          // 等比缩放
          if (this.blockScale > 0) {
            height = width / this.blockScale;
            y = orgBottom - height;
          }
          // 自由缩放
          else {
            y = Math.round(orgY + offsetY / this.myZoomScale);
            height = Math.max(orgBottom - y, 1);
          }
          this.myY = y;
          this.myWidth = width;
          this.myHeight = height;
          this.$maker.debounceUpdateCurrentBlockMeasure({
            y,
            width,
            height,
          });
        },
        //.....................................................
        SW: (ctx) => {
          let { orgX, orgWidth, orgHeight, offsetX, offsetY } = ctx;
          let orgRight = orgX + orgWidth;

          let x = Math.round(orgX + offsetX / this.myZoomScale);
          let width = Math.max(orgRight - x, 1);

          let height;
          // 等比缩放
          if (this.blockScale > 0) {
            height = width / this.blockScale;
          }
          // 自由缩放
          else {
            height = Math.round(orgHeight + offsetY / this.myZoomScale);
          }

          this.myX = x;
          this.myWidth = width;
          this.myHeight = height;
          this.$maker.debounceUpdateCurrentBlockMeasure({
            x,
            width,
            height,
          });
        },
        //.....................................................
        SE: (ctx) => {
          let { orgWidth, orgHeight, offsetX, offsetY } = ctx;
          let width = Math.round(orgWidth + offsetX / this.myZoomScale);

          let height;
          // 等比缩放
          if (this.blockScale > 0) {
            height = width / this.blockScale;
          }
          // 自由缩放
          else {
            height = Math.round(orgHeight + offsetY / this.myZoomScale);
          }

          this.myWidth = width;
          this.myHeight = height;
          this.$maker.debounceUpdateCurrentBlockMeasure({
            width,
            height,
          });
        },
        //.....................................................
        W: (ctx) => {
          let { orgX, orgWidth, orgHeight, offsetX } = ctx;
          let orgRight = orgX + orgWidth;
          let x = Math.round(orgX + offsetX / this.myZoomScale);
          let width = Math.max(orgRight - x, 1);
          let height;
          // 等比缩放
          if (this.blockScale > 0) {
            height = width / this.blockScale;
          }
          // 自由缩放
          else {
            height = orgHeight;
          }
          this.myX = x;
          this.myWidth = width;
          this.myHeight = height;
          this.$maker.debounceUpdateCurrentBlockMeasure({
            x,
            width,
            height,
          });
        },
        //.....................................................
        N: (ctx) => {
          let { orgY, orgWidth, orgHeight, offsetY } = ctx;
          let orgBottom = orgY + orgHeight;
          let y = Math.round(orgY + offsetY / this.myZoomScale);
          let height = Math.max(orgBottom - y, 1);
          let width;
          // 等比缩放
          if (this.blockScale > 0) {
            width = height * this.blockScale;
          }
          // 自由缩放
          else {
            width = orgWidth;
          }
          this.myY = y;
          this.myWidth = width;
          this.myHeight = height;
          this.$maker.debounceUpdateCurrentBlockMeasure({
            y,
            width,
            height,
          });
        },
        //.....................................................
        E: (ctx) => {
          let { orgWidth, orgHeight, offsetX } = ctx;
          let width = Math.round(orgWidth + offsetX / this.myZoomScale);
          let height;
          // 等比缩放
          if (this.blockScale > 0) {
            height = width / this.blockScale;
          }
          // 自由缩放
          else {
            height = orgHeight;
          }
          this.myWidth = width;
          this.myHeight = height;
          this.$maker.debounceUpdateCurrentBlockMeasure({
            width,
            height,
          });
        },
        //.....................................................
        S: (ctx) => {
          let { orgWidth, orgHeight, offsetY } = ctx;
          let height = Math.round(orgHeight + offsetY / this.myZoomScale);
          let width;
          // 等比缩放
          if (this.blockScale > 0) {
            width = height * this.blockScale;
          }
          // 自由缩放
          else {
            width = orgWidth;
          }
          this.myWidth = width;
          this.myHeight = height;
          this.$maker.debounceUpdateCurrentBlockMeasure({
            width,
            height,
          });
        },
        //.....................................................
        move: (ctx) => {
          let { orgX, orgY, offsetX, offsetY } = ctx;
          //console.log("dragging", {orgX, orgY, offsetX, offsetY})
          this.myX = Math.round(orgX + offsetX / this.myZoomScale);
          this.myY = Math.round(orgY + offsetY / this.myZoomScale);
          this.$maker.debounceUpdateCurrentBlockMeasure({
            x: this.myX,
            y: this.myY,
          });
        },
      };
    },
    //--------------------------------------
    Draggable() {
      return {
        activedDelay: 100,
        trigger: ($src, $el, { ctrlKey, shiftKey }) => {
          //console.log($src, $el, { ctrlKey, shiftKey })
          let $tri = Ti.Dom.closest($src, ".lvgl-maker-com-block") || $src;
          // 嵌套节点，只有选中，才能被拖拽
          if (
            Ti.Dom.hasClass($tri, "as-sub-block") &&
            Ti.Dom.hasClass($tri, "is-current")
          ) {
            // Then the trigger is the closed com-block of $src
          }
          // 找到自己所属的顶级节点
          else {
            // 寻找一条控件的节点链
            let $ps = Ti.Dom.parentsUntil($tri, ".as-com-wrapper", {
              iteratee: ($it) => Ti.Dom.hasClass($it, "lvgl-maker-com-block"),
              includeSelf: true,
              includeStop: false,
              reverse: true,
            });
            // 如果是 ctrl 被按下，则寻找自己，否则采用自己的父亲
            if (ctrlKey) {
              $tri = _.last($ps)
            } else {
              $tri = _.first($ps);
            }
            // 点在画布里 ...
            if (Ti.Dom.hasClass($tri, "as-com-con")) {
              this.OnSelectBlockItem({ name: null, shift: shiftKey });
            }
            // 点在控件上 ...
            else if (Ti.Dom.hasClass($tri, "lvgl-maker-com-block")) {
              let name = $tri.getAttribute("name");
              this.OnSelectBlockItem({ name, shift: shiftKey });
            }
          }
          //console.log("Draggable", $tri.getAttribute("name"), $tri)

          // 只有自由布局才能拖动
          // if ($tri.getAttribute("data-align") != "FREE") {
          //   // 禁止移动，但是可以允许 resize
          //   if (!$src.getAttribute("mode")) {
          //     return
          //   }
          // }

          return $tri;
        },
        viewport: ($trigger) => {
          return Ti.Dom.closest($trigger, ".as-com-con");
        },
        // testActive: ({ $trigger }) => {
        //   // 嵌套节点，只有选中，才能被拖拽
        //   if (Ti.Dom.hasClass($trigger, "as-sub-block")) {
        //     return Ti.Dom.hasClass($trigger, "is-current")
        //   }
        //   // 顶级节点，直接可以被拖拽
        //   let name = $trigger.getAttribute("name");
        //   this.OnSelectBlockItem({ name });
        //   return true
        // },
        actived: (ctx) => {
          //console.log("<Drag start>")
          this.$maker.stageInDragging = true;
          ctx.orgX = _.get(this.LvglCurrentBlock, "x");
          ctx.orgY = _.get(this.LvglCurrentBlock, "y");
          ctx.orgWidth = _.get(this.LvglCurrentBlock, "width");
          ctx.orgHeight = _.get(this.LvglCurrentBlock, "height");
          // Resize
          let mode = ctx.$event.srcElement.getAttribute("mode") || "move";
          // Move
          ctx.action = this.DragMethods[mode];
        },
        dragging: (ctx) => {
          ctx.action(ctx);
        },
        done: (ctx) => {
          this.$maker.updateCurrentBlockProp({
            x: this.myX,
            y: this.myY,
            width: this.myWidth,
            height: this.myHeight,
          });
          this.myX = undefined;
          this.myY = undefined;
          this.myWidth = undefined;
          this.myHeight = undefined;
          this.$maker.updateCurrentBlockMeasure({});
          _.delay(() => {
            this.$maker.stageInDragging = false;
          }, 0);
        },
      };
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    OnStageResize() {
      this.myMainRect = Ti.Rects.createBy(this.$refs.main);
      //console.log("OnStageResize", this.myMainRect.toString())
    },
    //--------------------------------------
    OnScreenChange(screenIndex) {
      this.$notify("select:screen", screenIndex * 1);
    },
    //--------------------------------------
    OnClickPartMain() {
      this.setActived();
      //this.$notify("select:block", {});
    },
    //--------------------------------------
    OnSelectBlockItem({ name, shift } = {}) {
      //console.log("OnSelectBlockItem", name)
      this.setActived();
      this.$notify("select:block", { name, shift });
    },
    //--------------------------------------
    OnClickPreviewButton() {
      this.$notify("lvgl:preview");
    },
    //--------------------------------------
    OnToggleOutlinePanel() {
      this.$notify("toggle:outline:panel");
    },
    //--------------------------------------
    joinViewBlockItems(list = [], blocks = []) {
      if (_.isArray(blocks) && blocks.length > 0) {
        for (let block of blocks) {
          // Join Self
          list.push(block);
          // Join Children
          this.joinViewBlockItems(list, block.blocks);
        }
      }
    },
    //--------------------------------------
    blinkBlock(blockName) {
      let $b = Ti.Dom.find(
        `.lvgl-maker-com-block[name='${blockName}']`,
        this.$el
      );
      Ti.Be.BlinkIt($b);
    },
    //-----------------------------------------------
    // Callback
    //-----------------------------------------------
    __ti_shortcut(uniqKey) {
      //console.log("Stage UKEY", uniqKey)
      let hdl = {
        DELETE: () => {
          this.$notify("remove:block:current");
        },
        "CTRL+ENTER": () => {
          this.$notify("insert:block");
        },
        ARROWLEFT: () => {
          let x = _.get(this.LvglCurrentBlock, "x");
          let step = this.keyboardMoveStep;
          this.$maker.updateCurrentBlockProp({ x: x - step });
        },
        ARROWRIGHT: () => {
          let x = _.get(this.LvglCurrentBlock, "x");
          let step = this.keyboardMoveStep;
          this.$maker.updateCurrentBlockProp({ x: x + step });
        },
        ARROWUP: () => {
          let y = _.get(this.LvglCurrentBlock, "y");
          let step = this.keyboardMoveStep;
          this.$maker.updateCurrentBlockProp({ y: y - step });
        },
        ARROWDOWN: () => {
          let y = _.get(this.LvglCurrentBlock, "y");
          let step = this.keyboardMoveStep;
          this.$maker.updateCurrentBlockProp({ y: y + step });
        },
        "CTRL+ARROWLEFT": () => {
          let x = _.get(this.LvglCurrentBlock, "x");
          let step = 1;
          this.$maker.updateCurrentBlockProp({ x: x - step });
        },
        "CTRL+ARROWRIGHT": () => {
          let x = _.get(this.LvglCurrentBlock, "x");
          let step = 1;
          this.$maker.updateCurrentBlockProp({ x: x + step });
        },
        "CTRL+ARROWUP": () => {
          let y = _.get(this.LvglCurrentBlock, "y");
          let step = 1;
          this.$maker.updateCurrentBlockProp({ y: y - step });
        },
        "CTRL+ARROWDOWN": () => {
          let y = _.get(this.LvglCurrentBlock, "y");
          let step = 1;
          this.$maker.updateCurrentBlockProp({ y: y + step });
        },
        "CTRL+C": () => {
          this.$maker.OnCopyLvglCom();
        },
        "CTRL+V": () => {
          this.$maker.OnPasteLvglCom();
        },
      }[uniqKey];
      // Invoke the handle
      if (_.isFunction(hdl)) {
        hdl();
      }
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  watch: {
    //device: "OnStageResize",
  },
  //////////////////////////////////////////
  created: function () {
    this.__debounce_stage_resize = _.debounce(() => {
      this.OnStageResize();
    }, 30);
    this.showPreviewButton = !this.$maker.isInVsCode;
  },
  //////////////////////////////////////////
  mounted: function () {
    Ti.Viewport.watch(this, {
      resize: () => {
        this.__debounce_stage_resize();
      },
    });
    // TODO 这个不知道为啥，不延迟一下，获取不了真实排版的宽高
    // 看 DOM 也没有加过渡效果，这个很奇怪
    _.delay(() => {
      this.OnStageResize();
    }, 500);
  },
  //////////////////////////////////////////
  beforeDestroy: function () {
    Ti.Viewport.unwatch(this);
  },
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'luo-tile-devlog.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/tile/devlog/luo-tile-devlog.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props : {
    "value": {
      type: Object,
      default: ()=>({})
    }
  },
  //////////////////////////////////////////
  computed : {
    //--------------------------------------
    TopClass() {
      return this.getTopClass()
    },
    //--------------------------------------
    Log() {
      let log = this.value || {}
      if(log.ct) {
        log.createTime = Ti.DateTime.format(log.ct)
      }
      return log
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods : {
    //--------------------------------------
    //--------------------------------------
  }
  //////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-led.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/led/lvgl-led.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    //-------------------------------------------
    bright: {
      type: Number,
      default: 255,
    },
    state: {
      type: String,
      default: "ON",
      validator: (v) => _.isNull(v) || /^(ON|OFF)$/.test(v),
    },
    //-------------------------------------------
    // Aspec
    //-------------------------------------------
    defaultStatus: {
      type: Object,
      default: undefined,
    },
  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    MyDisplayBright() {
      // if ("ON" == this.state) {
      //   return _.clamp(255 / 255, 0, 1)
      // }
      if ("OFF" == this.state) {
        return _.clamp(120 / 255, 0, 1);
      }
      return _.clamp(this.bright / 255, 0, 1);
    },
    //-------------------------------------------
    PartMainStyle() {
      let bg = _.get(this.defaultStatus, "mainPart.bg") || {};
      //
      // 根据亮度，调整颜色
      //
      let minBri = 0;
      let maxBri = 0.618;
      let { color, gradColor } = bg;
      let bri = this.MyDisplayBright;
      // 将亮度值限制在 0.382 至 0.8 之间
      var light = minBri + (maxBri - minBri) * bri;
      if (color) {
        let tColor = Ti.Types.toColor(color);
        tColor.updateByHSL({ l: light });
        color = tColor.hex;
        bg.color = color;
      }

      if (gradColor) {
        let tGradC = Ti.Types.toColor(gradColor);
        tGradC.updateByHSL({ l: light });
        gradColor = tGradC.hex;
        bg.gradColor = gradColor;
      }
      //
      // 转换 CSS
      //
      let css = this.getCssBackgroundStyle(bg);
      //
      // 如果有了亮度，则增加一个发光阴影
      //
      if (bri > 0 && this.width > 0) {
        let r = this.width * 0.5 * bri;
        css.boxShadow = `0 0 ${r}px ${color || "#FFF"}`;
      }
      return css;
    },
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-style-border.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/style/border/lvgl-maker-style-border.mjs'] = (function(){
////////////////////////////////////////////////////////
const _M = {
  //////////////////////////////////////////////////////
  props: {
    //-----------------------------------
    // Data
    //-----------------------------------
    value: {
      type: Object,
    },
  },
  //////////////////////////////////////////////////////
  computed: {
    //--------------------------------------------------
    StyleForm() {
      return {
        spacing: "comfy",
        fields: [
          {
            title: "边框颜色",
            name: "color",
            comType: "TiInputColor",
            comConf: {
              showAlpha: false,
            },
          },
          {
            title: "不透明度",
            name: "opa",
            type: "Integer",
            defaultAs: 255,
            comType: "TiInputNum",
            comConf: {
              step: 1,
              minValue: 0,
              maxValue: 255,
            },
          },
          {
            title: "边框宽度",
            name: "width",
            type: "Integer",
            defaultAs: 0,
            comType: "TiInputNum",
          },
          {
            title: "绘制边",
            name: "side",
            type: "Array",
            comType: "TiDroplist",
            comConf: {
              multi: true,
              options: ["LEFT", "RIGHT", "TOP", "BOTTOM", "FULL"],
            },
          },
          {
            title: "最后绘制",
            name: "post",
            type: "Boolean",
            comType: "TiToggle",
          },
          {
            title: "混合模式",
            name: "blendMode",
            comType: "TiSwitcher",
            comConf: {
              options: ["NORMAL", "ADDITIVE", "SUBTRACTIVE"],
            },
          },
        ],
      };
    },
    //--------------------------------------------------
  },
  //////////////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-style-line.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/style/line/lvgl-maker-style-line.mjs'] = (function(){
////////////////////////////////////////////////////////
const _M = {
  //////////////////////////////////////////////////////
  props: {
    //-----------------------------------
    // Data
    //-----------------------------------
    value: {
      type: Object,
    },
  },
  //////////////////////////////////////////////////////
  computed: {
    //--------------------------------------------------
    StyleForm() {
      return {
        spacing: "comfy",
        fields: [
          {
            title: "线条颜色",
            name: "color",
            comType: "TiInputColor",
            comConf: {
              showAlpha: false,
            },
          },
          {
            title: "不透明度",
            name: "opa",
            type: "Integer",
            defaultAs: 0,
            comType: "TiInputNum",
            comConf: {
              step: 1,
              minValue: 0,
              maxValue: 255,
            },
          },
          {
            title: "线条宽度",
            name: "width",
            type: "Integer",
            comType: "TiInputNum",
          },
          {
            title: "端点圆角",
            name: "rounded",
            type: "Boolean",
            comType: "TiToggle",
          },
        ],
      };
    },
    //--------------------------------------------------
  },
  //////////////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-style-bg.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/style/bg/lvgl-maker-style-bg.mjs'] = (function(){
////////////////////////////////////////////////////////
const _M = {
  //////////////////////////////////////////////////////
  props: {
    //-----------------------------------
    // Data
    //-----------------------------------
    value: {
      type: Object,
    },
  },
  //////////////////////////////////////////////////////
  computed: {
    //--------------------------------------------------
    StyleForm() {
      return {
        spacing: "comfy",
        fields: [
          {
            title: "背景色",
            name: "color",
            comType: "TiInputColor",
            comConf: {
              showAlpha: false,
            },
          },
          {
            title: "不透明度",
            name: "opa",
            type: "Integer",
            defaultAs: 255,
            comType: "TiInputNum",
            comConf: {
              step: 1,
              minValue: 0,
              maxValue: 255,
            },
          },
          {
            title: "渐变色",
            name: "gradColor",
            comType: "TiInputColor",
            comConf: {
              showAlpha: false,
            },
          },
          {
            title: "渐变开始",
            name: "mainStop",
            type: "Integer",
            defaultAs: 0,
            comType: "TiInputNum",
            comConf: {
              step: 10,
              minValue: 0,
              maxValue: 255,
            },
          },
          {
            title: "渐变结束",
            name: "gradStop",
            type: "Integer",
            defaultAs: 255,
            comType: "TiInputNum",
            comConf: {
              step: 10,
              minValue: 0,
              maxValue: 255,
            },
          },
          {
            title: "渐变方向",
            name: "gradDir",
            comType: "TiSwitcher",
            comConf: {
              options: ["NONE", "HOR", "VER"],
            },
          },
          {
            title: "混合模式",
            name: "blendMode",
            comType: "TiSwitcher",
            comConf: {
              options: ["NORMAL", "ADDITIVE", "SUBTRACTIVE"],
            },
          },
        ],
      };
    },
    //--------------------------------------------------
  },
  //////////////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-cont.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/cont/lvgl-cont.mjs'] = (function(){
// 控件行为文档： https://doc.openluat.com/wiki/21?wiki_page_id=2566
const _M = {
  ///////////////////////////////////////////////
  props: {
    "adjustLayout": {
      type: Function
    },
    //-------------------------------------------
    // Behaviors
    //-------------------------------------------
    "layout": {
      type: String,
      default: "LAYOUT_OFF",
      validator: v => /^LAYOUT_(OFF|CENTER|GRID|COLUMN_(LEFT|MID|RIGHT)|(ROW|PRETTY)_(TOP|MID|BOTTOM))$/.test(v)
    },
    "fit": {
      type: String,
      default: "FIT_NONE",
      validator: v => /^FIT_(NONE|TIGHT|PARENT|MAX)$/.test(v)
    },
    //-------------------------------------------
    // Aspec
    //-------------------------------------------
    "defaultStatus": {
      type: Object,
      default: undefined,
    },
  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    CurrentStyle() {
      return _.get(this.defaultStatus, "mainPart") || {}
    },
    //-------------------------------------------
    PartMainStyle() {
      let css = {};
      //.........................................
      //this.setCssPad(css, this.CurrentStyle.pad);
      this.setCssBackgroundStyle(css, this.CurrentStyle.bg);
      this.setCssBorder(css, this.CurrentStyle.border);
      //.........................................
      return css;
    },
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    doAdjustLayout() {
      this.adjustLayout({
        autoFit: this.fit,
        layout: this.layout,
        padding: this.CurrentStyle.pad
      })
    },
    //-------------------------------------------
    tryAdjustLayout(newVal, oldVal) {
      if (!_.isEqual(newVal, oldVal)) {
        this.doAdjustLayout()
      }
    }
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  watch: {
    "layout": {
      handler: "tryAdjustLayout",
      immediate: true
    },
    "fit": {
      handler: "tryAdjustLayout",
      immediate: true
    },
    "CurrentStyle": {
      handler: "tryAdjustLayout",
      immediate: true
    }
  }
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'm-my-buildsrv-methods.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['mod/buildsrv/m-my-buildsrv-methods.mjs'] = (function(){
////////////////////////////////////////////
const _M = {
  //----------------------------------------
  async doCreateNewBuild({ dispatch }) {
    // 获取项目名称
    let title = _.trim(await Ti.Prompt("请输入新构建名称"));

    // 用户取消
    if (!title)
      return

    // 提交
    await dispatch("createNewBuild", { title })
  },
  //----------------------------------------
  async doRemoveCurrentBuild({ dispatch, state }) {
    let build = state.currentBuild
    if (!build) {
      return
    }
    // 确认
    if (!(await Ti.Confirm(`您确定想彻底删除构建【${build.title || build.nm}】吗？所有的数据都将被删除且不可恢复`))) {
      return
    }
    await dispatch("removeCurrentBuild")
  },
  //----------------------------------------
  async doSwitchBuild({ state, commit, dispatch }) {
    let buildId = await Ti.App.Open({
      title: "选择构建",
      width: 400,
      height: 0.618,
      position: "top",
      comType: "TiList",
      comConf: {
        style: { padding: ".2em" },
        data: state.myBuildList,
        currentId: state.currentBuildId,
        display: ["<icon:fab-docker>", "title"],
        cancelable: false,
        onSelect: function ({ currentId }) {
          this.$notify("change", currentId)
        }
      },
      components: [
        "@com:ti/list"
      ]
    })

    if (!buildId)
      return

    commit("setCurrentBuildId", buildId)

    commit("setStatus", { reloading: true })
    await dispatch("reloadCurrentBuildConf")
    commit("setStatus", { reloading: false })
    commit("syncStatusChanged")
  },
  //----------------------------------------
  async openBuildConfEditor({ state, dispatch }) {
    // Guard
    if (!state.currentBuildId) {
      return await Ti.Toast.Open("i18n:empty-data", "warn")
    }
    // Open Editor
    let newContent = await Ti.App.Open({
      title: "编辑构建内容",
      width: "80%",
      height: "90%",
      position: "top",
      result: state.currentBuildConf,
      comType: "ti-text-raw",
      comConf: {
        placeholder: "无内容",
        showTitle: false,
        ignoreKeyUp: true
      },
      components: [
        "@com:ti/text/raw"
      ]
    })

    // Cancel the editing
    if (_.isUndefined(newContent)) {
      return
    }

    // Update the current editing
    await dispatch("updateCurrentBuildConf", newContent)
  }
  //----------------------------------------
}
return _M;;
})()
// ============================================================
// EXPORT 'workbench-methods.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/workbench/workbench-methods.mjs'] = (function(){
const __TI_MOD_EXPORT_VAR_NM = {
  
}
return __TI_MOD_EXPORT_VAR_NM;;
})()
// ============================================================
// EXPORT 'lvgl-maker-style-transition.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/style/transition/lvgl-maker-style-transition.mjs'] = (function(){
////////////////////////////////////////////////////////
const _M = {
  //////////////////////////////////////////////////////
  props: {
    //-----------------------------------
    // Data
    //-----------------------------------
    "value": {
      type: Object
    }
  },
  //////////////////////////////////////////////////////
  computed: {
    //--------------------------------------------------
    StyleForm() {
      return {
        spacing: "comfy",
        fields: [
          {
            "title": "过渡时长",
            "name": "time",
            "type": "Integer",
            "default": 0,
            "width": "1.5rem",
            "comType": "TiInput",
            "comConf": {
              "suffixText": "毫秒"
            }
          },
          {
            "title": "延迟",
            "name": "delay",
            "type": "Integer",
            "default": 0,
            "width": "1.5rem",
            "comType": "TiInput",
            "comConf": {
              "suffixText": "毫秒"
            }
          },
          {
            "title": "过渡属性",
            "name": "prop",
            "type": "Array",
            "comType": "TiDroplist",
            "comConf": {
              "multi": true,
              "options": [
                "WIDTH",
                "HEIGHT",
                "X",
                "Y",

                "PAD_TOP",
                "PAD_BOTTOM",
                "PAD_LEFT",
                "PAD_RIGHT",

                "BG_COLOR",
                "BG_OPA",

                "BORDER_COLOR",
                "BORDER_WIDTH",

                "SHADOW",

                "TEXT_COLOR",
                "TEXT_OPA",

                "RADIUS",
                "OPA"
              ]
            }
          }
        ]
      }
    }
    //--------------------------------------------------
  }
  //////////////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'm-my-workbench-methods.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['mod/workbench/m-my-workbench-methods.mjs'] = (function(){
////////////////////////////////////////////
const _M = {
  //----------------------------------------
  async doAddProjectFile({ dispatch }) {
    let fileName = _.trim(await Ti.Prompt("输入新文件名"))
    // 用户取消
    if (!fileName) {
      return
    }
    // 提交
    await dispatch("addProjectFile", fileName)
  },
  //----------------------------------------
  async doAddProjectDir({ dispatch }) {
    let dirName = _.trim(await Ti.Prompt("输入新文件夹名称"))
    // 用户取消
    if (!dirName) {
      return
    }
    // 提交
    await dispatch("addProjectDir", dirName)
  },
  //----------------------------------------
  async doCreateNewProject({ dispatch }) {
    // 获取项目名称
    let title = _.trim(await Ti.Prompt("请输入新项目名称"));

    // 用户取消
    if (!title)
      return

    // 提交
    await dispatch("createNewProject", { title })
  },
  //----------------------------------------
  async doRemoveCurrentProject({dispatch, state}) {
    let proj = state.currentProject
    if(!proj) {
      return
    }
    // 确认
    if(!(await Ti.Confirm(`您确定想彻底删除这项目【${proj.title||proj.nm}】吗？所有的数据都将被删除且不可恢复`))) {
      return
    }
    await dispatch("removeCurrentProject")
  },
  //----------------------------------------
  async doSwitchProject({ state, commit, dispatch }) {
    let projId = await Ti.App.Open({
      title: "选择项目",
      width: 400,
      height: 0.618,
      position: "top",
      comType: "TiList",
      comConf: {
        style: { padding: ".2em" },
        data: state.myProjects,
        display: ["<icon:fas-chess-rook>", "title"],
        onSelect: function ({ currentId }) {
          this.$notify("change", currentId)
        }
      },
      components: [
        "@com:ti/list"
      ]
    })

    if (!projId)
      return

    commit("setCurrentProjId", projId)
    await dispatch("reloadCurrentProjectFiles")
    commit("setCurrentFileId")
    commit("setCurrentFileContent")
    commit("syncStatusChanged")
  },
  //----------------------------------------
  async openFileContentEditor({ state, dispatch }) {
    // Guard
    if (!state.currentFile) {
      return await Ti.Toast.Open("i18n:empty-data", "warn")
    }
    // Open Editor
    let newContent = await Ti.App.Open({
      title: "编辑内容",
      width: "80%",
      height: "90%",
      position: "top",
      result: state.currentFileContent,
      comType: "ti-text-raw",
      comConf: {
        placeholder: "无内容",
        showTitle: false,
        ignoreKeyUp: true
      },
      components: [
        "@com:ti/text/raw"
      ]
    })

    // Cancel the editing
    if (_.isUndefined(newContent)) {
      return
    }

    // Update the current editing
    await dispatch("updateCurrentFileContent", newContent)
  }
  //----------------------------------------
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-checkbox.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/cb/lvgl-checkbox.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    //-------------------------------------------
    status: {
      type: String,
      default: "DEFAULT",
      validator: (v) =>
        /^(DEFAULT|(CHECKED_)?(RELEASED|PRESSED|DISABLED))$/.test(v),
    },
    text: {
      type: String,
    },
    checked: {
      type: Boolean,
      default: false,
    },
    //-------------------------------------------
    // Behavior
    //-------------------------------------------
    disabled: {
      type: Boolean,
      default: false,
    },
    //-------------------------------------------
    // Aspec
    //-------------------------------------------
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    releasedStatus: {
      type: Object,
      default: undefined,
    },
    pressedStatus: {
      type: Object,
      default: undefined,
    },
    checkedReleasedStatus: {
      type: Object,
      default: undefined,
    },
    checkedPressedStatus: {
      type: Object,
      default: undefined,
    },
    disabledStatus: {
      type: Object,
      default: undefined,
    },
    checkedDisabledStatus: {
      type: Object,
      default: undefined,
    },
  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    BulletClass() {
      if (this.checked) {
        return "far fa-check-square";
      }
      return "far fa-square";
    },
    //-------------------------------------------
    CurrentStyle() {
      let name = _.camelCase(`${this.status}_STATUS`);
      return this[name] || {} || {};
    },
    //-------------------------------------------
    CurrentBgPart() {
      return _.get(this.CurrentStyle, "bgPart") || {};
    },
    //-------------------------------------------
    CurrentBulletPart() {
      return _.get(this.CurrentStyle, "bulletPart") || {};
    },
    //-------------------------------------------
    BgStyle() {
      let part = this.CurrentBgPart;
      let css = {};
      //.........................................
      this.setCssBackgroundStyle(css, part.bg);

      let { color, opa, letterSpace, lineSpace, decor, font } = part.text || {};
      css.color = this.getCssColor(color, opa);
      this.setCssNumberProp(css, "letterSpacing", letterSpace);
      this.setCssNumberProp(css, "lineHeight", lineSpace);
      this.setCssTextDecoration(css, decor);
      this.setCssFont(css, font);
      //.........................................
      return css;
    },
    //-------------------------------------------
    BulletStyle() {
      let part = this.CurrentBulletPart;
      let css = {};
      //.........................................
      this.setCssBackgroundStyle(css, part.bg);
      //.........................................
      return css;
    },
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    notifyResizable() {
      //console.log("notifyResizable")
      let rsz = "auto";
      this.$notify("com:block:resizable", {
        [this.blockName]: rsz,
      });
    },
  },
  ///////////////////////////////////////////////
  watch: {
    text: {
      handler: "notifyResizable",
      immediate: true,
    },
  },
};
return _M;;
})()
// ============================================================
// EXPORT 'wb-devices.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/workbench/com/wb-devices/wb-devices.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props : {
    
  },
  //////////////////////////////////////////
  computed : {
    //--------------------------------------
    
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods : {
    //--------------------------------------
    //--------------------------------------
  }
  //////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'build-fonts.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/buildshop/editconf/build-fonts.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////////////
  methods: {
    //---------------------------------------------------
    genFontComConf(keepCustomizedTo) {
      return {
        newItemText: "添加字体配置",
        blankAs: {
          text: "并未配置任何字体"
        },
        //....................................
        list: {
          dftLabelHoverCopy: false,
          columnResizable: true,
          canCustomizedFields: true,
          keepCustomizedTo,
          fields: [
            {
              title: "命名",
              candidate: true,
              display: "name"
            },
            {
              title: "字体",
              display: "#MinkeBuildFonts(font_name)"
            },
            {
              title: "大小",
              display: "font_size"
            },
            {
              title: "类型",
              display: "font_type"
            },
            {
              title: "英文符号",
              candidate: true,
              display: "font_map_english"
            },
            {
              title: "定制字符",
              candidate: true,
              display: "font_map_custom"
            },
            {
              title: "简体中文",
              candidate: true,
              display: "font_map_simple"
            },
          ]
        },
        //....................................
        dialog: {
          title: "编辑字体配置",
          width: "4.8rem",
          height: "6.4rem"
        },
        //....................................
        form: {
          defaultComType: "TiInput",
          linkFields: {
            "font_name": {
              target: {
                "name": ":->${$update.value}_${font_type}_${font_size}"
              }
            },
            "font_type": {
              target: {
                "name": ":->${font_name}_${$update.value}_${font_size}"
              }
            },
            "font_size": {
              target: {
                "name": ":->${font_name}_${font_type}_${$update.value}"
              }
            }
          },
          fields: [
            {
              title: "命名",
              name: "name",
              disabled: true,
              comConf: {
                readonly: true
              }
            },
            {
              title: "字体",
              name: "font_name",
              comType: "TiDroplist",
              comConf: {
                options: "#MinkeBuildFonts",
                suffixText: ":=value"
              }
            },
            {
              title: "大小",
              name: "font_size",
              type: "Integer",
              comType: "TiInputNum",
              comConf: {
                minValue: 8,
                maxValue: 48,
                step: 2
              }
            },
            {
              title: "类型",
              name: "font_type",
              comType: "TiDroplist",
              comConf: {
                options: "#MinkeBuildFontTypes(=name)",
                dictVars: {
                  name: ":=item.font_name"
                },
                "dropDisplay": "text"
              }
            },
            {
              title: "映射方式",
              name: "font_map_type",
              defaultAs: "custom",
              comType: "TiSwitcher",
              comConf: {
                options: [
                  { value: "simple", text: "直选映射" },
                  { value: "custom", text: "定制映射" },
                ]
              }
            },
            {
              title: "英文符号",
              name: "font_map_english",
              type: "Boolean",
              hidden: {
                font_map_type: "simple"
              },
              comType: "TiToggle"
            },
            {
              title: "定制字符",
              name: "font_map_custom",
              hidden: {
                font_map_type: "simple"
              },
              nameVAlign: "top",
              comType: "TiInputText",
              comConf: {
                height: "12em"
              }
            },
            {
              title: "简体中文",
              name: "font_map_simple",
              visible: {
                font_map_type: "simple"
              },
              comType: "TiDroplist",
              comConf: {
                options: [
                  "gb2312", "gb2312a", "gb2312b", "chinese1", "chinese2"
                ],
                dropDisplay: "text"
              }
            },
          ]
        }
      }
    }
    //---------------------------------------------------
  }
  ///////////////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'build-editconf.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/buildshop/editconf/build-editconf.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////////////
  props: {
    "buildMetas": {
      type: Array,
      default: () => []
    },
    "data": {
      type: String
    },
    "dataFile": {
      type: Object
    },
    "currentBuild": {
      type: Object
    },
    "status": {
      type: Object
    }
  },
  ///////////////////////////////////////////////////////
  computed: {
    //---------------------------------------------------
    hasBuildMetas() { return !_.isEmpty(this.buildMetas) },
    hasData() { return !_.isEmpty(this.data) },
    //---------------------------------------------------
    AvaChipNames() {
      return _.map(this.buildMetas, ({ nm }) => {
        if (nm.endsWith(".meta.json")) {
          return nm.substring(0, nm.length - 10)
        }
        return nm
      })
    },
    //---------------------------------------------------
    CurrentData() {
      if (this.hasData) {
        return JSON.parse(this.data)
      }
      return null
    },
    //---------------------------------------------------
    CurrentChipName() {
      return _.get(this.CurrentData, "chip")
    },
    //---------------------------------------------------
    CurrentBuildMeta() {
      if (this.CurrentChipName && this.hasBuildMetas) {
        let metaName = `${this.CurrentChipName}.meta.json`
        for (let bm of this.buildMetas) {
          if (metaName == bm.nm) {
            return _.cloneDeep(bm.content)
          }
        }
      }
      return {};
    },
    //---------------------------------------------------
    CurrentChip() {
      return _.get(this.CurrentBuildMeta, "builder.chip") || {}
    },
    //---------------------------------------------------
    SDKList() {
      let list = []
      let presets = _.get(this.CurrentBuildMeta, "builder.sdk.presets")
      _.forEach(presets, ({ name, value } = {}) => {
        if (name) {
          list.push({ value: name, text: name, setup: value })
        }
      })
      return list
    },
    //---------------------------------------------------
    CurrentComponents() {
      let re = {}
      let buildComponents = _.get(this.CurrentData, "component")
      _.forEach(buildComponents, (val, key) => {
        if (val) {
          re[key] = true
        }
      })
      return re
    },
    //---------------------------------------------------
    TreeData() {
      return _.get(this.CurrentBuildMeta, "builder.component")
    },
    //---------------------------------------------------
    TreeConfig() {
      return {
        display: [
          "<icon>", "content::flex-auto",
          "name::flex-none as-tip-block align-right"],
        showRoot: false,
        idBy: "name",
        nameBy: "name",
        autoOpen: true,
        puppetMode: true,
        defaultOpenDepth: 100,
        hoverable: true,
        checkable: true,
        spacing: "tiny",
        border: "row",
        onNodeSelect: (payload) => {
          this.OnTreeNodeSelect(payload)
        },
        checkedIds: this.CurrentComponents

      }
    },
    //---------------------------------------------------
    FormData() {
      let re = _.pick(this.CurrentData,
        "id", "version", "chip", "sdkName",
        "memory", "layout", "script", "fonts",
        "component");
      re.dataFile = this.dataFile
      return re
    },
    //---------------------------------------------------
    FormFields() {
      return [
        {
          title: "构建ID",
          name: "id",
          comConf: {
            className: "is-nowrap",
            suffixIconForCopy: true
          }
        },
        {
          icon: "fas-microchip",
          title: "模块",
          name: "chip",
          comType: "TiDroplist",
          comConf: {
            options: this.AvaChipNames,
            allowEmpty: false
          }
        },
        {
          icon: "fas-sd-card",
          title: "脚本区",
          name: "script",
          type: "Integer",
          comType: "TiSlideStack",
          comConf: {
            precision: 0,
            stacks: {
              title: "脚本区大小",
              name: "script",
              min: _.get(this.CurrentChip, "script.min"),
              max: _.get(this.CurrentChip, "script.max"),
              dft: _.get(this.CurrentChip, "script.dft"),
              unit: _.get(this.CurrentChip, "script.unit")
            }
          }
        },
        {
          title: "自定义字库(u8g2系列)"
        },
        {
          name: "fonts.u8g2",
          type: "Array",
          tip: "适用于u8g2/lcd/eink库",
          valueWrap: "wrap",
          comType: "TiComboTable",
          comConf: this.genFontComConf("Mink-BuildSrv-EditConf-Fonts-u8g2-table")
        },
        // {
        //   title: "自定义字库(lvgl系列)"
        // },
        // {
        //   name: "fonts.lvgl",
        //   type: "Array",
        //   tip: "适用于lvgl库",
        //   valueWrap: "wrap",
        //   comType: "TiComboTable",
        //   comConf: this.genFontComConf("Mink-BuildSrv-EditConf-Fonts-lvgl-table")
        // }
        /*
        {
          icon: "fas-memory",
          title: "内存",
          name: "memory",
          type: "Integer",
          comType: "TiSlideStack",
          comConf: {
            precision: 0,
            stacks: {
              title: "内存",
              name: "memory",
              min: _.get(this.CurrentChip, "memory.min"),
              max: _.get(this.CurrentChip, "memory.max"),
              dft: _.get(this.CurrentChip, "memory.dft")
            }
          }
        },
        {
          icon: "fas-sd-card",
          title: "磁盘",
          name: "layout",
          type: "Object",
          comType: "TiSlideStack",
          comConf: {
            capacity: _.get(this.CurrentChip, "layout.total"),
            precision: 0,
            stacks: [
              {
                title: "ROM",
                name: "rom",
                min: _.get(this.CurrentChip, "layout.rom.min"),
                max: _.get(this.CurrentChip, "layout.rom.max"),
                dft: _.get(this.CurrentChip, "layout.rom.dft")
              },
              {
                title: "FS",
                name: "fs",
                min: _.get(this.CurrentChip, "layout.fs.min"),
                max: _.get(this.CurrentChip, "layout.fs.max"),
                dft: _.get(this.CurrentChip, "layout.fs.dft")
              }
            ]
          }
        },
        {
          icon: "fas-toolbox",
          title: "SDK",
          name: "sdkName",
          comType: "TiSwitcher",
          comConf: {
            options: this.SDKList,
            allowEmpty: false
          }
        },
        {
          icon: "fas-file-alt",
          title: "文件",
          name: "dataFile",
          hidden: true,  // Wendal 说暂时先隐藏掉
          comType: "WebUploadFile",
          comConf: {
            supportTypes: ["zip"],
            uploadParams: {
              ts: "buildsrv",
              fnm: "custom.zip",
              id: _.get(this.CurrentData, "id")
            },
            getFileDownloadLink: {
              url: "/api/thing/file/read",
              params: {
                ts: "buildsrv",
                id: _.get(this.CurrentData, "id"),
                fnm: "custom.zip",
                down: true
              }
            },
            defaultPreviewIcon: "fas-file-archive",
            uploadedBy: "file:uploaded"
          }
        }
        */
      ]
    },
    //---------------------------------------------------
    TheLayout() {
      return {
        type: "cols",
        border: true,
        keepCustomizedTo: "Minke-BuildShop-Layout-Conf-Col",
        blocks: [
          {
            name: "form",
            size: "37.2%",
            body: "form"
          },
          {
            name: "tree",
            body: "tree"
          }
        ]
      }
    },
    //---------------------------------------------------
    TheSchema() {
      let readonly = this.BuildStatus > 0
      return {
        "form": {
          comType: "TiForm",
          comConf: {
            spacing: "comfy",
            fieldNameWrap: "wrap",
            fieldNameAlign: "left",
            data: this.FormData,
            fields: this.FormFields
          }
        },
        "tree": {
          comType: "TiTree",
          comConf: {
            data: this.TreeData,
            ... this.TreeConfig,
            hoverable: !readonly,
            checkable: !readonly,
            selectable: !readonly
          }
        }
      }
    },
    //---------------------------------------------------
    BuildStatus() {
      return _.get(this.currentBuild, "build_stat") || 0
    }
    //---------------------------------------------------
  },
  ///////////////////////////////////////////////////////
  methods: {
    //---------------------------------------------------
    OnFormChange() { },
    //---------------------------------------------------
    OnFormFieldChange({ name, value }) {
      let data = _.cloneDeep(this.FormData)
      _.set(data, name, value)
      // 通知改动
      this.notifyChange(data)
    },
    //---------------------------------------------------
    OnTreeNodeSelect({ currentId } = {}) {
      // 防守
      if (!currentId) {
        return
      }
      // Toggle 选择
      let isOn = this.CurrentComponents[currentId] ? false : true

      // 得到子节点名称列表
      //console.log(currentId, isOn)
      let childNames = []
      const findChildNames = function (itemList = [], isFound = false) {
        // Guard
        if (_.isEmpty(itemList)) {
          return
        }
        // Check each list
        for (let item of itemList) {
          let itName = item.name
          if (itName) {
            if (isFound) {
              childNames.push(itName)
            }
          }
          // 递归
          findChildNames(item.children, isFound || (itName == currentId))
        }
      }
      findChildNames(this.TreeData)

      // 设置子节点列表
      let coms = _.cloneDeep(this.CurrentComponents)
      coms[currentId] = isOn
      for (let childName of childNames) {
        coms[childName] = isOn
      }

      // 最后检查一下，之输出哪些为true的组件信息
      let re = {}
      _.forEach(coms, (val, key) => {
        if (val) {
          re[key] = true
        }
      })

      // 融合，通知改动
      let data = _.cloneDeep(this.FormData)
      data.component = re
      // 通知改动
      this.notifyChange(data)
    },
    //---------------------------------------------------
    notifyChange(data = {}) {
      this.$notify("change", data)
    }
    //---------------------------------------------------
  }
  ///////////////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'm-my-workbench-gencode.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['mod/workbench/m-my-workbench-gencode.mjs'] = (function(){
////////////////////////////////////////////
/*
LVGL 代码树:
{
  "screenA": [
    /* 每条语句一个对象，对象有 vars 以及 type 表示占位符以及语句类型
    { type: "STYLE_INIT", vars: {}},
    { type: "STYLE_SET", vars: {}},
    { type: "COM_CREATE", vars: {}},
    { type: "COM_PROP", vars: {}},
  ]
}
*/
////////////////////////////////////////////
const STATEMENTS_HANDLES = {
  "STYLE_INIT": (comName) => {
    return ``
  },
  "STYLE_SET": (comName) => {
    return ``
  },
  "COM_CREATE": (comName, { comType }) => {
    return ``
  },
  "COM_SET_POS": (comName, { x, y }) => {
    return ``
  },
  "COM_SET_SIZE": (comName, { width, height }) => {
    return ``
  },
  "COM_PROP": (comName, { key, val }) => {
    return ``
  }
};
////////////////////////////////////////////
class LvglLuaStatement {
  constructor(type, comName, vars = {}) {
    this.comName = comName
    this.type = type
    this.vars = vars
  }
  valueOf() {
    return this.toString()
  }
  toString() {
    let fn = STATEMENTS_HANDLES[this.type]
    return fn(this.comName, this.vars)
  }
  toDebug() {
    return `lua:> ${this.type}[${this.comName}] : ${JSON.stringify(this.vars)}`
  }
}
////////////////////////////////////////////
class LvglLuaBlock {
  constructor() {
    this.list = []
  }
  push(type, comName, vars) {
    let st = new LvglLuaStatement(type, comName, vars)
    this.list.push(st)
  }
  isEmpty() {
    return _.isEmpty(this.list)
  }
  toString() {
    let lines = []
    for (let li of this.list) {
      lines.push(li.toString())
    }
    return lines.join("\n")
  }
  toDebug() {
    let lines = []
    for (let li of this.list) {
      lines.push(li.toDebug())
    }
    return lines.join("\n")
  }
}
////////////////////////////////////////////
const COM_PROP_HANDLES = {
  _default: (luaBody, comName, comConf = {}) => {
    _.forEach(comConf, (val, key) => {
      if (!key.endsWith("Status") && !key.endsWith("Part")) {
        luaBody.push("COM_PROP", comName, { key, val })
      }
    })
  }
}
////////////////////////////////////////////
const _M = {
  lvglGenerateCode({ state, commit, dispatch, rootState }, lvgl = {}) {
    let schema = lvgl.schema || {}
    let screens = {}
    //......................................
    const joinCom = (luaBody, name, com = {}) => {
      let { comType, comConf } = com
      // 创建控件
      luaBody.push("COM_CREATE", name, { comType })

      // 设置控件属性
      let setComProp = COM_PROP_HANDLES[comType] || COM_PROP_HANDLES._default
      setComProp(luaBody, name, comConf)
    };
    //......................................
    // 准备块处理代码
    const joinBlock = (luaBody, block) => {
      let {
        name, type,
        width, height, x, y,
        align,
        body, blocks
      } = block

      // 找到目标控件
      let com = schema[body]
      if (!com) {
        throw `Fail to found lvgl.schema[${name}]`
      }

      // 创建控件
      joinCom(luaBody, name, com)

      // 设置控件位置
      luaBody.push("COM_SET_POS", name, { x, y })
      luaBody.push("COM_SET_SIZE", name, { width, height })

      // 递归处理子块
      if (!_.isEmpty(blocks)) {
        // 记入控件
        for (let subBlock of blocks) {
          joinBlock(luaBody, subBlock)
        }
      }
    };
    //......................................
    // 按照 Screen 生成代码语句
    for (let screen of lvgl.screens) {
      let { name, layout } = screen
      let luaBody = new LvglLuaBlock()
      if (layout && layout.blocks && layout.blocks.length > 0) {
        for (let block of layout.blocks) {
          joinBlock(luaBody, block)
        }
      }
      // 记入语句
      if (name && !luaBody.isEmpty()) {
        screens[name] = luaBody
      }
    }
    //......................................
    // 每个屏幕变成一个函数

    //......................................
    // 生成主函数
  }
}
////////////////////////////////////////////
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-label.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/label/lvgl-label.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    //-------------------------------------------
    text: {
      type: String,
    },
    longMode: {
      type: String,
      default: "LABEL_LONG_EXPAND",
      validator: (v) =>
        /^LABEL_LONG_(EXPAND|BREAK|DOT|SROLL|SROLL_CIRC|CROP)$/.test(v),
    },
    //-------------------------------------------
    // Aspec
    //-------------------------------------------
    align: {
      type: String,
      default: "LABEL_ALIGN_LEFT",
      validator: (v) =>
        Ti.Util.isNil(v) || /^LABEL_ALIGN_(LEFT|RIGHT|CENTER)$/.test(v),
    },
    recolor: {
      type: Boolean,
      default: false,
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    zoomScale: {
      type: Number,
      default: 1,
    },
  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    TopClass() {
      let longMode = _.kebabCase(this.longMode);
      return this.getTopClass(`is-${longMode}`);
    },
    //-------------------------------------------
    CurrentStyle() {
      return _.get(this.defaultStatus, "mainPart") || {};
    },
    //-------------------------------------------
    TopStyle() {
      let css = {};
      // if (this.longMode == "LABEL_LONG_EXPAND") {
      //   css.width = "auto";
      //   css.height = "auto";
      // }
      return css;
    },
    //-------------------------------------------
    PartMainStyle() {
      let css = {
        display: "flex",
        justifyContent: "center",
        alignItems: "top",
        alignContent: "center",
        width: "100%",
        height: "100%",
      };

      if (this.align) {
        css.textAlign = this.align.replace("LABEL_ALIGN_", "");
      }
      //.........................................
      this.setCssBackgroundStyle(css, this.CurrentStyle.bg);
      //.........................................
      return css;
    },
    //-------------------------------------------
    PartTextStyle() {
      let css = {
        width: "100%",
        position: "relative",
      };
      //.........................................
      this.setCssText(css, this.CurrentStyle.text, this.zoomScale);
      return css;
    },
    //-------------------------------------------
    ValueText() {
      return this.text || "Label";
    },
    ValueHtml() {
      return this.getLabelHtml(this.ValueText, this.recolor, true);
    },
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    notifyResizable() {
      //console.log("notifyResizable")
      let rsz = "LABEL_LONG_EXPAND" == this.longMode ? "auto" : true;
      this.$notify("com:block:resizable", {
        [this.blockName]: rsz,
      });
    },
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  watch: {
    longMode: {
      handler: "notifyResizable",
      immediate: true,
    },
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-qrcode.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/qrcode/lvgl-qrcode.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  data: () => ({
    qrObj: null,
  }),
  ///////////////////////////////////////////////
  props: {
    txt: {
      type: String,
      default: "",
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    heightReal: 0,
    widthReal: 0,
  },
  ///////////////////////////////////////////////
  computed: {
    CurrMainStyle() {
      return _.get(this.defaultStatus, "mainPart") || {};
    },
    //-------------------------------------------
    ImageStyle() {
      let bgStyle = this.getCssBackgroundStyle(this.CurrMainStyle.bg || {});
      return bgStyle;
    },
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    //-------------------------------------------
    renderQrcode() {
      if (this.qrObj) {
        this.qrObj.clear(); // clear the code.
        this.qrObj.makeCode(this.txt); // make another code
      } else {
        let $qrcode = this.$refs.qrcode;
        let params = {
          text: this.txt || "https://luatos.com/",
          width: this.widthReal || 128,
          height: this.heightReal || 128,
          colorDark: "#000000",
          colorLight: "#ffffff",
          correctLevel: QRCode.CorrectLevel.H,
        };
        console.log("qr-init:" + JSON.stringify(params));
        this.qrObj = new QRCode($qrcode, params);
      }
    },
  },
  ///////////////////////////////////////////////
  watch: {
    txt() {
      this.renderQrcode();
    },
  },
  mounted() {
    setTimeout(this.renderQrcode, 100);
    // this.renderQrcode();
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'workbench-source-tree.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/workbench/workbench-source-tree.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////////////
  props: {
    "projectFiles": {
      type: Array,
      default: () => []
    },
    "currentFileId": {
      type: String,
    }
  },
  ///////////////////////////////////////////////////////
  computed: {
    //---------------------------------------------------
    //---------------------------------------------------
  },
  ///////////////////////////////////////////////////////
  methods: {
    //---------------------------------------------------
    //---------------------------------------------------
  }
  ///////////////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-slider.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/slider/lvgl-slider.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  data: () => ({}),
  ///////////////////////////////////////////////
  props: {
    value: {
      type: [Number, Array],
      default: 0,
    },
    range: {
      type: Array,
      default: [0, 100],
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    heightReal: 0,
    widthReal: 0,
  },
  ///////////////////////////////////////////////
  computed: {
    isHorizontal() {
      return this.widthReal >= this.heightReal;
    },
    containerWidth() {
      return this.isHorizontal ? this.widthReal : this.heightReal;
    },
    containerHeight() {
      return this.isHorizontal ? this.heightReal : this.widthReal;
    },
    //-------------------------------------------
    BarObj() {
      if (_.isNumber(this.value)) {
        return { val: this.value, animat: false };
      }
      if (_.isArray(this.value)) {
        return {
          val: _.nth(this.value, 0),
          animat: "ANIM_ON" == _.nth(this.value, 1),
        };
      }
      return { val: this.range[0], animat: false };
    },
    //-------------------------------------------
    BarValue() {
      return this.BarObj.val;
    },
    CurrBgStyle() {
      return _.get(this.defaultStatus, "bgPart") || {};
    },
    CurrIndicStyle() {
      return _.get(this.defaultStatus, "indicPart") || {};
    },
    CurrKnobStyle() {
      return _.get(this.defaultStatus, "knobPart") || {};
    },
    PartBgStyle() {
      let bgStyle = this.getCssBackgroundStyle(this.CurrBgStyle.bg || {});
      bgStyle.borderRadius = this.containerHeight * 0.95 + "px";
      bgStyle.marginTop = this.containerHeight * 0.025 + "px";
      bgStyle.height = this.containerHeight * 0.95 + "px";
      let bgPad = this.CurrBgStyle ? this.CurrBgStyle.pad : null;
      if (bgPad) {
        Object.keys(bgPad).forEach(
          (pos) =>
            (bgStyle[this.toCamelCase("padding-" + pos)] = bgPad[pos] + "px")
        );
      }
      return bgStyle;
    },
    PartIndicStyle() {
      let indicStyle = this.getCssBackgroundStyle(this.CurrIndicStyle.bg || {});
      indicStyle.borderTopLeftRadius = this.containerHeight * 0.95 + "px";
      indicStyle.borderBottomLeftRadius = this.containerHeight * 0.95 + "px";
      indicStyle.borderTopRightRadius = "0px";
      indicStyle.borderBottomRightRadius = "0px";
      indicStyle.width = this.CurrPosWidth(this.containerWidth) + "px";
      let bgPad = this.CurrBgStyle ? this.CurrBgStyle.pad : null;
      if (bgPad) {
        let h = this.containerHeight;
        if (bgPad.top) {
          h -= bgPad.top;
        }
        if (bgPad.bottom) {
          h -= bgPad.bottom;
        }
        indicStyle.borderTopLeftRadius = h * 0.95 + "px";
        indicStyle.borderBottomLeftRadius = h * 0.95 + "px";
        let w = this.containerWidth;
        if (bgPad.left) {
          w -= bgPad.left;
        }
        if (bgPad.right) {
          w -= bgPad.right;
        }
        indicStyle.width = this.CurrPosWidth(w) + "px";
      }
      return indicStyle;
    },
    PartKnobStyle() {
      let currRange = parseInt(this.range[1]);
      let currValue = parseInt(this.BarValue);
      let currLeft =
        this.containerWidth * (currValue / currRange) -
        this.containerHeight * 0.5;

      let knobStyle = this.getCssBackgroundStyle(this.CurrKnobStyle.bg || {});
      knobStyle.width = this.containerHeight + "px";
      knobStyle.height = this.containerHeight + "px";
      knobStyle.borderRadius = this.containerHeight * 0.95 + "px";
      knobStyle.left = currLeft + "px";

      // 内边距
      let knobPad = this.CurrKnobStyle ? this.CurrKnobStyle.pad : null;
      if (knobPad) {
        let h = this.containerHeight;
        if (knobPad.top) {
          knobStyle.top = knobPad.top * -1 + "px";
          h += knobPad.top;
        }
        if (knobPad.bottom) {
          h += knobPad.bottom;
        }
        knobStyle.height = h + "px";
        knobStyle.borderRadius = h * 0.95 + "px";

        let w = this.containerHeight;
        let posw = this.containerWidth;
        if (knobPad.left) {
          w += knobPad.left;
          currLeft -= knobPad.left / 2;
        }
        if (knobPad.right) {
          w += knobPad.right;
          currLeft -= knobPad.right / 2;
        }
        knobStyle.width = w + "px";
        knobStyle.left = currLeft + "px";
      }
      return knobStyle;
    },
    containerStyle() {
      let css = {
        width: "100%",
        height: "100%",
      };
      // 垂直的时候
      if (!this.isHorizontal) {
        css.width = this.containerWidth + "px";
        css.height = this.containerHeight + "px";
        css.transform = `rotate(270deg) translateX(-${this.containerWidth}px)`;
        css.transformOrigin = "0 0";
      }
      return css;
    },
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    //-------------------------------------------
    CurrPosWidth(maxWidth) {
      let currRange = parseInt(this.range[1]);
      let currValue = parseInt(this.BarValue);
      let width = (currValue / currRange) * maxWidth;
      return width;
    },
  },
  ///////////////////////////////////////////////
  watch: {},
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'wb-source-tree.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/workbench/com/wb-source-tree/wb-source-tree.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////////////
  data: () => ({
    myOpenedNodePaths: {}
  }),
  ///////////////////////////////////////////////////////
  props: {
    "data": {
      type: Array
    },
    "currentId": {
      type: String
    }
  },
  ///////////////////////////////////////////////////////
  computed: {
    //---------------------------------------------------
    TreeDisplay() {
      return [
        {
          key: ["icon", "tp", "race", "nm"],
          transformer: ({ icon = "far-file", tp, race, nm } = {}) => {
            if("lvgl" == tp) {
              return  "fas-drafting-compass"
            }
            if("DIR" == race) {
              if("images" == nm) {
                return "fas-images"
              }
              return "fas-folder"
            }
            return icon
          },
          comType: "TiIcon"
        },
        'nm'
      ]
    },
    //---------------------------------------------------
  },
  ///////////////////////////////////////////////////////
  methods: {
    //---------------------------------------------------
    OnTreeInit($tree) {
      this.$tree = $tree
    },
    //---------------------------------------------------
    OnNodeOpened() {

    },
    //---------------------------------------------------
    OnTreeOpenedStatusChange(openedPath) {
      this.myOpenedNodePaths = _.omitBy(openedPath, v => !v)
      if (this.keepOpenBy) {
        Ti.Storage.session.setObject(this.keepOpenBy, openedPath)
      }
    },
    //---------------------------------------------------
  }
  ///////////////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'm-my-workbench-actions.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['mod/workbench/m-my-workbench-actions.mjs'] = (function(){
////////////////////////////////////////////
function API_URL({ apiBase } = {}, path) {
  return Ti.Util.appendPath(apiBase, path);
}
////////////////////////////////////////////
const _M = {
  //----------------------------------------
  async viewTranslateResult({ dispatch }) {
    let luaCode = await dispatch("translateCurrentFileToLua");

    await Ti.App.Open({
      title: "转换后代码",
      width: "80%",
      height: "96%",
      position: "top",
      result: luaCode,
      comType: "TiTextCodeAce",
      comConf: {
        mode: "lua",
        height: "100%"
      }
    })
  },
  //----------------------------------------
  async translateCurrentFileToLua({ state, dispatch }) {
    let lvglFile = state.currentFile
    // 当前的文件是否是一个 lvgl 文件呢？
    if (!lvglFile) {
      Ti.Toast.Open("请选择一个LVGL文件对象!", "warn");
      return
    }
    // 防守
    if ("lvgl" != lvglFile.tp) {
      Ti.Toast.Open("只有LVGL文件对象才能被转换为Luat!", "warn");
      return
    }
    // 得到这个文件的内容
    let json = _.trim(state.currentFileContent) || "{}";
    let lvgl = JSON.parse(json);

    if (_.isEmpty(lvgl)) {
      Ti.Toast.Open("LVGL 文件没有任何内容!", "warn");
      return
    }

    // 准备返回代码
    let luaCode = null;

    // 模拟代码
    luaCode = await Ti.Load("/lvgl/main.lua")
    // console.log("TODO: LVGL代码生成:", luaCode);

    // 转换代码
    //luaCode = await dispatch("lvglGenerateCode", lvgl)

    // 返回
    return luaCode;
  },
  //----------------------------------------
  async previewCurrentFile({ state, commit, dispatch, rootState }) {
    // 当前的文件是否是一个 lvgl 文件呢？
    if (!state.currentFile) {
      return Ti.Toast.Open("请选择一个要在模拟终端显示的文件对象!", "warn");
    }
    // 准备 Lua 代码
    let luaCode = null;
    let deviceWidth = 640
    let deviceHeight = 480
    //
    // Luat 代码直接显示
    //
    if ("lua" == state.currentFile.tp) {
      luaCode = state.currentFileContent
    }
    //
    // Lvgl 文件，得到一个转换内容 
    //
    else if ("lvgl" == state.currentFile.tp) {
      deviceWidth = _.get(lvgl, "device.width")
      deviceHeight = _.get(lvgl, "device.height")
      luaCode = await dispatch("translateCurrentFileToLua")
    }

    // 打开模拟器
    await Ti.App.Open({
      title: "LuatOS终端模拟器",
      position: "center",
      width: "96%",
      height: "96%",
      textOk: null,
      textCancel: 'i18n:close',
      result: luaCode,
      comType: "LvglSimulator",
      comConf: {
        deviceWidth, deviceHeight
      },
      components: [
        "@Site:com/lvgl/simulator"
      ]
    })
  },
  //----------------------------------------
  async createNewProject({ commit, dispatch, rootState }, proj) {
    if (!proj) {
      return;
    }
    let url = API_URL(rootState, "thing/create");
    let reo = await Ti.Http.post(url, {
      params: {
        ticket: rootState.auth.ticket,
        ts: "projects",
      },
      body: JSON.stringify(
        _.assign(proj, {
          user_id: rootState.auth.me.OID.myId,
        })
      ),
      as: "json",
    });

    await dispatch("reloadMyProject");
    commit("setCurrentProjId", reo.id);
    commit("setCurrentProjectFiles");
    commit("setCurrentFileId");
    commit("setCurrentFileContent");
    commit("syncStatusChanged");
  },
  //----------------------------------------
  async removeCurrentProject({ state, commit, dispatch, rootState }) {
    let projId = state.currentProjId;
    if (!projId) {
      return;
    }
    let url = API_URL(rootState, "thing/delete");
    await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket,
        ts: "projects",
        id: projId,
        hard: true,
      },
    });

    await dispatch("reloadMyProject");
    commit("setCurrentProjId", null);
    dispatch("autoSelectCurrentProject");

    await dispatch("reloadCurrentProjectFiles");
    commit("setCurrentFileId");
    commit("setCurrentFileContent");
    commit("syncStatusChanged");
  },
  //----------------------------------------
  async addProjectFile({ commit, dispatch, state, rootState }, fileName) {
    if (!fileName || !state.currentProjId) {
      return;
    }
    let url = API_URL(rootState, "project/file/add");
    let reo = await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket,
        projId: state.currentProjId,
        fileName,
      },
      as: "json",
    });

    await dispatch("reloadCurrentProjectFiles");
    commit("setCurrentFileId", reo.id);
    await dispatch("reloadCurrentFileContent");
  },
  //----------------------------------------
  async addProjectDir({ commit, dispatch, state, rootState }, dirName) {
    if (!dirName || !state.currentProjId) {
      return;
    }
    let url = API_URL(rootState, "project/file/add_dir");
    let reo = await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket,
        projId: state.currentProjId,
        dirName: dirName,
      },
      as: "json",
    });

    await dispatch("reloadCurrentProjectFiles");
    commit("setCurrentFileId", reo.id);
    await dispatch("reloadCurrentDirList");
  },
  //----------------------------------------
  async selectCurrentFile({ state, commit, dispatch }, currentId) {
    // 防守
    if (!state.currentProjId) {
      return;
    }

    commit("setCurrentFileContent", null);
    commit("setList", []);
    commit("setCurrentFileId", currentId);
    await dispatch("reloadCurrentFileContent");
    await dispatch("reloadCurrentDirList");

    // 保存到本地
    let cuIds = Ti.Storage.local.getObject("minke-wb-proj-currentIds", {});
    cuIds[state.currentProjId] = currentId;
    Ti.Storage.local.setObject("minke-wb-proj-currentIds", cuIds);
  },
  //----------------------------------------
  async removeCurrentProjectFile({ commit, dispatch, state, rootState }) {
    if (!state.currentFileId) {
      return;
    }
    // 如果当前是文件夹，那么看看是否是需要删除文件夹里面的内容
    let delIds = Ti.Util.truthyKeys(state.checkedIds);
    let isRemoveDirItems = true;
    // 如果是空，那么试图删除当前项目
    if (_.isEmpty(delIds)) {
      delIds = [state.currentFileId];
      isRemoveDirItems = false;
    }
    let url = API_URL(rootState, "obj/delete");
    await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket,
        id: delIds.join(","),
      },
      as: "json",
    });
    if (isRemoveDirItems) {
      await dispatch("reloadCurrentDirList");
      commit("setCurrentId", null);
      commit("setCheckedIds", {});
    }
    // 那么就重新加载项目文件树吧
    else {
      await dispatch("reloadCurrentProjectFiles");
      commit("setCurrentFileId", null);
      commit("setCurrentFileContent");
    }
    commit("syncStatusChanged");
  },
  //----------------------------------------
  async renameCurrentProjectFile({ commit, dispatch, state, rootState }) {
    let { currentId, currentFileId } = state;
    if (!currentFileId) {
      return await Ti.Toast.Open("请选择要改名的对象", "warn");
    }
    // 如果当前是文件夹，那么看看是否是需要改名文件夹里面的内容
    let obj = state.currentFile;
    let isRenameDirItem = false;
    if (currentId) {
      obj = _.find(state.list, (li) => li.id == currentId);
      isRenameDirItem = true;
    }

    // 询问一个新名称
    let newName = await Ti.Prompt("请输入新的对象名", {
      placeholder: obj.nm,
      value: obj.nm,
    });

    newName = _.trim(newName);
    if (!newName) {
      return;
    }

    // 检查名称
    let oldSuffix = Ti.Util.getSuffix(obj.nm);
    let newSuffix = Ti.Util.getSuffix(newName);

    if (!newSuffix && oldSuffix) {
      if (
        await Ti.Confirm(
          "我们发现您删除了对象的后缀名，需要我们自动为您加回去吗？"
        )
      ) {
        newName += oldSuffix;
      }
    }
    // 后缀名不相同
    else if (oldSuffix != newSuffix) {
      if (
        !(await Ti.Confirm(
          "我们发现您修改了对象的后缀名，您确认这是您特意的吗？【是】维持这个改动；【否】我们将恢复回原来的后缀名"
        ))
      ) {
        newName = Ti.Util.getMajorName(newName) + oldSuffix;
      }
    }

    // 执行名称的修改
    let url = API_URL(rootState, "obj/update");
    let reo = await Ti.Http.post(url, {
      body: JSON.stringify({ nm: newName }),
      params: {
        ticket: rootState.auth.ticket,
        id: obj.id,
      },
      as: "json",
    });
    if (isRenameDirItem) {
      commit("setListItem", reo);
    }
    // 那么就重新加载项目文件树吧
    else {
      await dispatch("reloadCurrentProjectFiles");
    }
    commit("syncStatusChanged");
  },
  //----------------------------------------
  async saveCurrentFileContent({ commit, state, rootState }) {
    if (!state.currentFile) {
      return await Ti.Toast.Open("没有选择任何文件", "warn");
    }
    let content = state.currentFileContent;
    commit("setStatus", { saving: true });
    let url = API_URL(rootState, "/write");
    let reo = await Ti.Http.post(url, {
      params: {
        ticket: rootState.auth.ticket,
        id: state.currentFileId,
      },
      body: content || "",
      as: "json",
    });
    commit("setStatus", { saving: false });
    commit("updateProjectFileItem", reo);
    commit("setCurrentFileContent", content);
    commit("setCurrentFileSavedContent", content);
    commit("syncStatusChanged");
  },
  //----------------------------------------
  updateCurrentFileContent({ commit }, content = null) {
    commit("setCurrentFileContent", content);
    commit("syncStatusChanged");
  },
  //----------------------------------------
  async autoSelectCurrentProject({ state, commit, dispatch }) {
    // 从本地恢复
    let projId = Ti.Storage.local.getString("minke-wb-current-proj");
    // Select the first project
    if (!projId) {
      let first = _.first(state.myProjects);
      projId = _.get(first, "id");
    }
    commit("setCurrentProjId", projId);
    // 自动恢复当前项目的选中文件项
    await dispatch("restoreProjectCurrentFile");
  },
  //----------------------------------------
  async restoreProjectCurrentFile({ state, dispatch }) {
    // 防守一道
    if (!state.currentProjId) {
      return;
    }
    // 每个 Project 都有一个搞亮的项目，这个默认关系存在 local 了
    let cuIds = Ti.Storage.local.getObject("minke-wb-proj-currentIds", {});
    let cuId = cuIds[state.currentProjId];

    // 如果找到了对应关系，选择它
    if (cuId) {
      await dispatch("selectCurrentFile", cuId);
    }
  },
  //----------------------------------------
  async reloadCurrentFileContent({ commit, state, rootState }) {
    let { currentFile } = state;
    if (!currentFile || !currentFile.sha1) {
      commit("setCurrentFileContent", null);
      return;
    }

    // Reload content
    commit("setCurrentFileContent");
    commit("setStatus", { reloading: true });
    let url = API_URL(rootState, "/read");
    let reo = await Ti.Http.get(url, {
      params: {
        f: currentFile.sha1,
        mime: currentFile.mime,
      },
    });
    commit("setStatus", { reloading: false });
    commit("setCurrentFileContent", reo);
  },
  //----------------------------------------
  async reloadCurrentDirList({ commit, state, rootState }) {
    let { currentProjId, currentFile } = state;
    if (!currentProjId || !currentFile || "DIR" != currentFile.race) {
      commit("setList", []);
      return;
    }

    // Reload content
    commit("setStatus", { reloading: true });
    let url = API_URL(rootState, "/project/file/reload_dir");
    let reo = await Ti.Http.get(url, {
      params: {
        projId: currentProjId,
        nm: currentFile.nm,
      },
      as: "json",
    });
    commit("setList", reo);
    commit("setStatus", { reloading: false });
  },
  //----------------------------------------
  async selectUploadProjectImageFile() {
    // 这个脏一点，找控件 TiAdaptlist，然后调用它里面的方法上传文件
    let app = Ti.App.topInstance();
    let $al = app.$vm().findComBy((com) => {
      return com.tiComType == "TiAdaptlist";
    });
    if (!$al) {
      return await Ti.Toast.Open("请选择一个文件夹，然后再上传文件", "warn");
    }

    // 打开本地文件选择对话框
    $al.openLocalFileSelectdDialog();
  },
  //----------------------------------------
  async uploadFileToCurrentDir(
    { commit, state, rootState },
    { file, progress } = {}
  ) {
    let { currentProjId, currentFile } = state;
    commit("setStatus", { saving: true });
    let url = API_URL(rootState, "/project/file/upload");
    let reo = await Ti.Http.post(url, {
      file,
      progress,
      params: {
        projId: currentProjId,
        dir: currentFile.nm,
        fnm: file.uploadName || file.name,
      },
      as: "json",
    });
    commit("setStatus", { saving: false });
    return reo;
  },
  //----------------------------------------
  async reloadCurrentProjectFiles({ commit, state, rootState }) {
    let { currentProjId } = state;
    if (!currentProjId) {
      commit("setCurrentProjectFiles", []);
      return;
    }
    let url = API_URL(rootState, "/project/file/reload");
    commit("setStatus", { reloading: true });
    let reo = await Ti.Http.get(url, {
      params: {
        ticket: rootState.auth.ticket,
        id: currentProjId,
      },
      as: "json",
    });
    commit("setStatus", { reloading: false });
    commit("setCurrentProjectFiles", reo);
  },
  //----------------------------------------
  async reloadMyProject({ commit, rootState }) {
    let url = API_URL(rootState, "/thing/list");
    let uid = _.get(rootState, "auth.me.OID.myId");
    commit("setStatus", { reloading: true });
    let reo = await Ti.Http.get(url, {
      params: {
        ts: "projects",
        m: {
          user_id: uid,
        },
        s: {
          ct: -1,
        },
      },
      as: "json",
    });
    commit("setStatus", { reloading: false });
    commit("setMyProjects", reo);
  },
  //----------------------------------------
  async reload({ commit, dispatch }) {
    commit("setStatus", { reloading: true });

    await dispatch("reloadMyProject");

    dispatch("autoSelectCurrentProject");

    await dispatch("reloadCurrentProjectFiles");
    await dispatch("reloadCurrentFileContent");
    await dispatch("reloadCurrentDirList");

    commit("setStatus", { reloading: false });
  },
  //----------------------------------------
};
return _M;;
})()
// ============================================================
// EXPORT 'luo-tile-device.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/tile/device/luo-tile-device.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  props : {
    "value": {
      type: Object,
      default: ()=>({})
    }
  },
  //////////////////////////////////////////
  computed : {
    //--------------------------------------
    TopClass() {
      return this.getTopClass()
    },
    //--------------------------------------
    Dev() {
      return this.value || {}
    },
    //--------------------------------------
    LogPageHref() {
      return `${this.base}my/devlog.html?nm=${this.Dev.nm}`
    },
    //--------------------------------------
    TrackPageHref() {
      return `${this.base}my/devtrack.html?nm=${this.Dev.nm}`
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods : {
    //--------------------------------------
    async OnClickRemove() {
      // 确认
      if(!(await Ti.Confirm(`您确认要删除设备【${this.Dev.nm}】吗？本操作无法撤销！`))) {
        return
      }

      // 提示删除
      this.$notify("dev:remove", this.Dev.id)
    }
    //--------------------------------------
  }
  //////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-switch.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/switch/lvgl-switch.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    state: {
      type: Boolean,
      default: false,
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
    heightReal: 0,
    widthReal: 0,
    zoomScale: {
      type: Number,
      default: 1,
    },
    width: 0,
    height: 0,
  },
  ///////////////////////////////////////////////
  computed: {
    CurrBgStyle() {
      return _.get(this.defaultStatus, "bgPart") || {};
    },
    CurrIndicStyle() {
      return _.get(this.defaultStatus, "indicPart") || {};
    },
    CurrKnobStyle() {
      return _.get(this.defaultStatus, "knobPart") || {};
    },
    PartBgStyle() {
      let bgStyle = this.getCssBackgroundStyle(this.CurrBgStyle.bg || {});
      bgStyle.borderRadius = this.heightReal / 2 + "px";
      let bgPad = this.CurrBgStyle ? this.CurrBgStyle.pad : null;
      if (bgPad) {
        Object.keys(bgPad).forEach(
          (pos) =>
            (bgStyle[this.toCamelCase("padding-" + pos)] = bgPad[pos] + "px")
        );
      }
      return bgStyle;
    },
    PartIndicStyle() {
      let indicStyle = this.getCssBackgroundStyle(this.CurrIndicStyle.bg || {});
      indicStyle.borderRadius = this.heightReal / 2 + "px";
      indicStyle.width = this.state ? "100%" : "0%";
      return indicStyle;
    },
    PartKnobStyle() {
      let bs = 1;
      let bw = 4 - bs;
      let knobHeight = this.heightReal - 4 * 2;
      let knobStyle = this.getCssBackgroundStyle(this.CurrKnobStyle.bg || {});
      knobStyle.width = knobHeight + "px";
      knobStyle.height = knobHeight + "px";
      knobStyle.borderRadius = knobHeight / 2 + "px";
      knobStyle.top = bw + "px";
      let knobPad = this.CurrKnobStyle ? this.CurrKnobStyle.pad : null;
      if (knobPad) {
        let kheight = knobHeight;
        if (knobPad.top) {
          knobStyle.top = bw + knobPad.top * -1 + "px";
          kheight += knobPad.top;
        }
        if (knobPad.bottom) {
          kheight += knobPad.bottom;
        }
        knobStyle.height = kheight + "px";
        knobStyle.borderRadius = kheight / 2 + "px";

        let kwidth = knobHeight;
        if (knobPad.left) {
          kwidth += knobPad.left;
        }
        if (knobPad.right) {
          kwidth += knobPad.right;
        }
        knobStyle.width = kwidth + "px";
      }
      if (this.state) {
        knobStyle.right = bw + "px";
        if (knobPad && knobPad.right) {
          knobStyle.right = bw + knobPad.right * -1 + "px";
        }
      } else {
        knobStyle.left = bw + "px";
        if (knobPad && knobPad.left) {
          knobStyle.left = bw + knobPad.left * -1 + "px";
        }
      }
      return knobStyle;
    },
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'mock-data.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/mock-data.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  mounted() {
    this.myDataDevice = {
      width: 640,
      height: 480
    }
    this.myDataScreens = [
      {
        name: "ScreenA",
        layout: {
          type: "free",
          blocks: [
            {
              name: "BlockA",
              width: 100,
              height: 60,
              x: 79,
              y: 87,
              body: "BlockA"
            },
            {
              name: "BlockB",
              width: 140,
              height: 80,
              x: 10,
              y: 300,
              body: "BlockB"
            }
          ]
        }
      },
      {
        name: "ScreenB",
        layout: {
          type: "free",
          blocks: [
            {
              name: "BlockC",
              width: 100,
              height: 60,
              x: 79,
              y: 87,
              body: "BlockC"
            },
            {
              name: "BlockD",
              width: 140,
              height: 80,
              x: 183,
              y: 360,
              body: "BlockD"
            },
            {
              name: "BlockE",
              width: 120,
              height: 101,
              x: 143,
              y: 23,
              body: "BlockE"
            }
          ]
        }
      }
    ]
    this.myDataSchema = {
      "BlockA": {
        comType: "LvglLabel",
        comConf: {
          text: "Label A"
        }
      },
      "BlockB": {
        comType: "LvglArc",
        comConf: {
          
        }
      },
      "BlockC": {
        comType: "LvglButton",
        comConf: {
          
        }
      },
      "BlockD": {
        comType: "LvglLabel",
        comConf: {
          text: "Label D"
        }
      },
      "BlockE": {
        comType: "LvglLabel",
        comConf: {
          text: "Label E"
        }
      }
    }
  }
}
//////////////////////////////////////////
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-arc.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/core/arc/lvgl-arc.mjs'] = (function(){
const calcCircumference = (r) => {
  return Math.PI * r * 2;
};

const _M = {
  ///////////////////////////////////////////////
  props: {
    value: {
      type: Number,
      default: 0,
    },
    range: {
      type: Array,
      default: () => [0, 100],
    },
    bgStartAngle: {
      type: Number,
      default: 0,
    },
    bgEndAngle: {
      type: Number,
      default: 0,
    },
    rotation: {
      type: Number,
      default: 0,
    },
    heightReal: 0,
    widthReal: 0,
    zoomScale: {
      type: Number,
      default: 1,
    },
    width: 0,
    height: 0,
    type: {
      type: String,
      default: "ARC_TYPE_NORMAL",
    },
    adjustable: {
      type: Boolean,
      default: false,
    },
    defaultStatus: {
      type: Object,
      default: undefined,
    },
  },
  data() {
    return {
      lineR: 90,
      lineX: 100,
      lineY: 100,
      indicR: 90,
      indicX: 100,
      indicY: 100,
    };
  },
  ///////////////////////////////////////////////
  computed: {
    CurrBgStyle() {
      return _.get(this.defaultStatus, "bgPart") || {};
    },
    CurrIndicStyle() {
      return _.get(this.defaultStatus, "indicPart") || {};
    },
    CurrKnobStyle() {
      return _.get(this.defaultStatus, "knobPart") || {};
    },
    arcBgStyle() {
      let css = {};
      css.transform = `rotate(${this.rotation / 360}turn)`;
      this.setCssBackgroundStyle(css, this.CurrBgStyle.bg || {});
      return css;
    },
    bgStyle() {
      let scale = (this.width / 200) * this.zoomScale;
      let css = {
        transform: `scale(${scale})`,
        transformOrigin: "0 0",
      };
      return css;
    },
    lineStyle() {
      let maxC = calcCircumference(this.lineR);
      let startAngel = this.getSafeAngle(this.bgStartAngle);
      let endAngel = this.getSafeAngle(this.bgEndAngle);
      let per = 1;
      let rotation = startAngel;
      if (startAngel >= endAngel) {
        per = 1 - (360 - startAngel + endAngel) / 360;
      } else {
        per = 1 - (endAngel - startAngel) / 360;
      }
      let css = {
        strokeDasharray: maxC,
        strokeDashoffset: maxC * per,
        transform: `rotate(${rotation}deg)`,
        transformOrigin: "100px 100px",
      };

      // 背景色
      this.setCssLineStyle(css, this.CurrBgStyle.line || {});
      // console.log("line-style:" + JSON.stringify(css));
      return css;
    },
    indicStyle() {
      let maxC = calcCircumference(this.indicR);

      // 计算当前value
      let curr = this.value;
      let max = this.range[1] - this.range[0];
      if (curr > this.range[1]) {
        curr = this.range[1];
      }
      if (curr < this.range[0]) {
        curr = this.range[0];
      }
      if (this.type == "ARC_TYPE_REVERSE") {
        curr = max - curr;
      }

      // 计算角度
      let per = 1;
      let startAngel = this.getSafeAngle(this.bgStartAngle);
      let endAngel = this.getSafeAngle(this.bgEndAngle);
      let rotation = startAngel;
      if (startAngel >= endAngel) {
        per = (360 - startAngel + endAngel) / 360;
      } else {
        per = (endAngel - startAngel) / 360;
      }

      // 缺失部分
      let offset = maxC - maxC * per;
      let maxCurr = maxC - offset;
      let perCurr = curr / max;

      // 正向
      let dashOffset = 0;
      if (this.type == "ARC_TYPE_NORMAL") {
        dashOffset = maxCurr - maxCurr * perCurr + offset;
      }

      // 反向
      if (this.type == "ARC_TYPE_REVERSE") {
        dashOffset = (maxCurr - maxCurr * perCurr + offset) * -1;
        rotation = endAngel;
      }

      // 对称
      if (this.type == "ARC_TYPE_SYMMETRIC") {
        // 中间角度与中间值
        if (startAngel >= endAngel) {
          per = (360 - startAngel + endAngel) / 2 / 360;
        } else {
          per = (endAngel - startAngel) / 2 / 360;
        }
        rotation = startAngel + 360 * per;

        // 50% 分界线
        let maxHalf = maxCurr / 2;
        let perHalf = 1;
        let rangeHalf = max / 2;
        let offsetHalf = 0;
        // 左边
        if (curr <= rangeHalf) {
          perHalf = (rangeHalf - curr) / rangeHalf;
          offsetHalf = maxHalf * perHalf;
          dashOffset = (maxC - offsetHalf) * -1;
        }
        // 右边
        else {
          perHalf = (curr - rangeHalf) / rangeHalf;
          offsetHalf = maxHalf * perHalf;
          dashOffset = maxC - offsetHalf;
        }
      }

      let css = {
        strokeDasharray: maxC,
        strokeDashoffset: dashOffset,
        transform: `rotate(${rotation}deg)`,
        transformOrigin: "100px 100px",
      };

      this.setCssLineStyle(css, this.CurrIndicStyle.line || {});
      return css;
    },
    knobStyle() {
      let css = {};
      if (this.adjustable) {
        let maxC = calcCircumference(this.indicR);
        css = Object.assign({}, this.indicStyle);
        css.strokeDasharray = `0px ${maxC}px`;
        css.stroke = "#03707A";
        css.strokeWidth = "1.5em";
      }
      // console.log("knob-style:" + JSON.stringify(css));
      this.setCssLineStyle(css, this.CurrKnobStyle.bg || {});
      return css;
    },
  },
  ///////////////////////////////////////////////
  methods: {
    getSafeAngle(a) {
      if (a <= 0) {
        return 0;
      }
      if (a > 360) {
        return 360;
      }
      return a;
    },
    //-------------------------------------------
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-simulator.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/simulator/lvgl-simulator.mjs'] = (function(){
const _M = {
  ///////////////////////////////////////////////
  data: () => ({
    myLogs: [],
    myCode: undefined,
    iAmReady: false
  }),
  ///////////////////////////////////////////////
  props: {
    //-------------------------------------------
    // Data
    //-------------------------------------------
    "value": {
      type: String,
      default: null,
    },
    //-------------------------------------------
    // Behaviors
    //-------------------------------------------
    "frameSrc": {
      type: String,
      default: "/lvgl/simulator.html"
    },
    //-------------------------------------------
    // Measure
    //-------------------------------------------
    "deviceWidth": {
      type: Number,
      default: 640
    },
    "deviceHeight": {
      type: Number,
      default: 480
    }
  },
  ///////////////////////////////////////////////
  computed: {
    //-------------------------------------------
    WinLogCallbackName() {
      return ['lvgl_log', this.tiComId.replace(':', '_')].join("_");
    },
    //-------------------------------------------
    FramePostEvents() {
      return "init:simulator"
    },
    //-------------------------------------------
    FramePostPayload() {
      return {
        code: this.myCode,
        callbackName: this.WinLogCallbackName
      }
    }
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  methods: {
    //-------------------------------------------
    //-------------------------------------------
  },
  ///////////////////////////////////////////////
  watch: {
    "value": {
      handler: function (val) {
        this.myCode = val
        this.iAmReady = val ? true : false
      },
      immediate: true
    }
  },
  ///////////////////////////////////////////////
  created: function () {
    window[this.WinLogCallbackName] = (line) => {
      let $logs = this.$refs.logs
      let t = Date.now()
      let it = {
        timestamp: t,
        index: this.myLogs.length,
        text: line
      }
      this.myLogs = _.concat(this.myLogs, it)
      this.$nextTick(() => {
        $logs.scrollTop = $logs.scrollHeight + 1000
      })
    }
  },
  ///////////////////////////////////////////////
  mounted: async function () {
    //await this.loadDemoCode()
  },
  ///////////////////////////////////////////////
  beforeDestroy: function () {
    delete window[this.WinLogCallbackName]
  }
  ///////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-style-shadow.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/style/shadow/lvgl-maker-style-shadow.mjs'] = (function(){
////////////////////////////////////////////////////////
const _M = {
  //////////////////////////////////////////////////////
  props: {
    //-----------------------------------
    // Data
    //-----------------------------------
    value: {
      type: Object,
    },
  },
  //////////////////////////////////////////////////////
  computed: {
    //--------------------------------------------------
    StyleForm() {
      return {
        spacing: "comfy",
        fields: [
          {
            title: "阴影颜色",
            name: "color",
            comType: "TiInputColor",
            comConf: {
              showAlpha: false,
            },
          },
          {
            title: "不透明度",
            name: "opa",
            type: "Integer",
            defaultAs: 255,
            comType: "TiInputNum",
            comConf: {
              step: 1,
              minValue: 0,
              maxValue: 255,
            },
          },
          {
            title: "模糊宽度",
            name: "width",
            type: "Integer",
            defaultAs: 0,
            comType: "TiInputNum",
            comConf: {
              placeholder: 0,
            },
          },
          {
            title: "X轴位移",
            name: "ofsX",
            type: "Integer",
            defaultAs: 0,
            comType: "TiInputNum",
          },
          {
            title: "Y轴位移",
            name: "ofsY",
            type: "Integer",
            defaultAs: 0,
            comType: "TiInputNum",
          },
          {
            title: "扩展",
            name: "spread",
            type: "Integer",
            defaultAs: 0,
            comType: "TiInputNum",
          },
          {
            title: "混合模式",
            name: "blendMode",
            comType: "TiSwitcher",
            comConf: {
              options: ["NORMAL", "ADDITIVE", "SUBTRACTIVE"],
            },
          },
        ],
      };
    },
    //--------------------------------------------------
  },
  //////////////////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'stage-block.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/stage/com/stage-block/stage-block.mjs'] = (function(){
const _M = {
  //////////////////////////////////////////
  inject: ["$maker", "$stage"],
  //////////////////////////////////////////
  data: () => ({
    myMea: {}
  }),
  //////////////////////////////////////////
  props: {
    "block": {
      type: Object,
      default: () => ({})
    },
    "isTopBlock": {
      type: Boolean,
      default: true
    },
    //......................................
    "parentLayout": {
      type: String,
      default: "LAYOUT_OFF"
    },
    "parentAutoFit": {
      type: String,
      default: "FIT_NONE"
    },
    //......................................
    // 顶级控件，就表示画布的逻辑尺寸
    // 子控件，就表示父控件的逻辑尺寸
    // {left,top,width,height}
    "viewportRect": {
      type: Object,
      default: () => ({})
    },
    //......................................
    // By-Pass Props
    //......................................
    "projectId": {
      type: String
    },
    "apiBase": {
      type: String
    },
    "zoomScale": {
      type: Number,
      default: undefined
    }
  },
  //////////////////////////////////////////
  computed: {
    //--------------------------------------
    TopClass() {
      return this.getTopClass(
        this.block.className,
        `is-${this.BlockAutoFit}`,
        `is-${this.BlockLayout}`,
        {
          'has-parent-layout': this.hasParentLayout
        })
    },
    //--------------------------------------
    isCurrent() {
      return this.block.current
    },
    //--------------------------------------
    InlayStyleId() {
      if (this.isScrollable) {
        return 'IS_' + _.snakeCase(this.tiComId.replace(/:/g, "_"))
      }
    },
    //--------------------------------------
    InlayStyleRule() {
      // Guard
      if (!this.InlayStyleId) {
        return
      }
      // 输出内嵌样式，主要是滚动条的颜色
      let IS = `.block-main[inlay-id="${this.InlayStyleId}"]`;
      return `
        <style>
        /*整体宽高*/
        ${IS} > .as-block-children::-webkit-scrollbar {
          width: 10px; height: 10px;
        }
        /*背景滚动槽*/
        ${IS} > .as-block-children::-webkit-scrollbar-track {
          opacity: 0;
        }
        /*前景滑块*/
        ${IS} > .as-block-children::-webkit-scrollbar-thumb {
          background: rgba(0,0,0,0.6);
        }
        /*右下方拖动方块*/
        ${IS} > .as-block-children::-webkit-scrollbar-corner  {
          visibility: hidden;
        }
        </style>
        `
    },
    //--------------------------------------
    TopStyle() {
      if (/^FIT_(PARENT|MAX)$/.test(this.BlockAutoFit)) {
        let css = {}
        if ("FIT_PARENT" == this.BlockAutoFit) {
          _.assign(css, {
            "width": "100%",
            "height": "100%",
          })
        } else {
          // 顶级容器控件，直接设置 100%
          if (this.isTopBlock) {
            _.assign(css, {
              "width": "100%",
              "height": "100%",
            })
          }
          // 否则跟随
          else {
            _.assign(css, {
              // "min-width": "100%",
              // "min-height": "100%",
              "width": "100%",
              "height": "100%",
            })
          }
          _.assign(css, {
            "display": "flex",
            "flex-direction": "column",
            "flex-wrap": "nowrap",
            "justify-content": "stretch",
            "align-items": "stretch"
          })
        }
        if (!_.isEmpty(this.BlockPad)) {
          this.setCssPad(css, this.BlockPad)
        }
        return css
      }
      return _.omit(this.myMea.style, "width", "height")
    },
    //--------------------------------------
    MainStyle() {
      if ("FIT_NONE" == this.BlockAutoFit) {
        return _.pick(this.myMea.style, "width", "height")
      }
      if (/^FIT_PARENT$/.test(this.BlockAutoFit)) {
        return {
          width: "100%",
          height: "100%"
        }
      }
      if (/^FIT_MAX$/.test(this.BlockAutoFit)) {
        return {
          "flex-basis": "100%"
        }
      }
    },
    //--------------------------------------
    SelfComStyle() {
      if ("FIT_NONE" != this.BlockAutoFit) {
        return {
          position: "absolute",
          top: 0,
          left: 0,
          right: 0,
          bottom: 0,
          zIndex: 0
        }
      }
    },
    //--------------------------------------
    ChildrenConClass() {
      return Ti.Css.mergeClassName(
        _.kebabCase(this.BlockLayout),
        _.kebabCase(this.BlockAutoFit),
      )
    },
    //--------------------------------------
    ChildrenStyle() {
      let css = {};
      // 自适应父，那么由顶层元素来控制边距
      if (!/^FIT_(PARENT|MAX)$/.test(this.BlockAutoFit)) {
        this.setCssPad(css, this.BlockPad)
      }
      // 如果要自适应，那么不要绝对定位
      if ("FIT_NONE" != this.BlockAutoFit) {
        _.assign(css, {
          position: "relative",
          top: "unset",
          left: "unset",
          right: "unset",
          bottom: "unset",
          zIndex: 1
        })
      }

      // 滚动条模式
      if (this.isScrollable) {
        css.overflow = ({
          "SCRLBAR_MODE_OFF": "visible",
          "SCRLBAR_MODE_ON": "scroll",
          "SCRLBAR_MODE_DRAG": "auto",
          "SCRLBAR_MODE_AUTO": "auto",
          "SCRLBAR_MODE_HIDE": "hidden",
          "SCRLBAR_MODE_UNHIDE": "scroll"
        })[this.BlockScrollMode] || "visible"
      }

      // 搞定
      return Ti.Css.toStyle(css)
    },
    //--------------------------------------
    ChildrenItemStyle() {
      if (this.BlockPad.inner) {
        let s = this.zoomScale || 1
        return Ti.Css.toStyle({
          padding: this.BlockPad.inner * s
        })
      }
    },
    //--------------------------------------
    BlockAlignment() {
      return this.block.align || "FREE"
    },
    //--------------------------------------
    // 注入给子控件的一个属性回调，譬如 cont 等控件
    // 可以通过这个回调来控制块的布局
    AdjustLayout() {
      return (blockLayout) => {
        this.$notify("change:block:props", blockLayout)
      }
    },
    //--------------------------------------
    BlockPad() {
      return _.get(this.block, "padding") || {}
    },
    //--------------------------------------
    BlockLayout() {
      return _.get(this.block, "layout") || "LAYOUT_OFF"
    },
    //--------------------------------------
    BlockAutoFit() {
      return _.get(this.block, "autoFit") || "FIT_NONE"
    },
    //--------------------------------------
    BlockScrollMode() {
      return _.get(this.block, "scrollMode")
    },
    //--------------------------------------
    hasLayout() {
      return "LAYOUT_OFF" != this.BlockLayout
    },
    //--------------------------------------
    hasAutoFit() {
      return "FIT_NONE" != this.BlockAutoFit
    },
    //--------------------------------------
    isScrollable() {
      return this.BlockScrollMode ? true : false
    },
    //--------------------------------------
    hasParentLayout() {
      return this.parentLayout && "LAYOUT_OFF" != this.parentLayout
    }
    //--------------------------------------
  },
  //////////////////////////////////////////
  methods: {
    //--------------------------------------
    OnClickTop({ ctrlKey, shiftKey }) {
      // 2022-07-07 zozoh: 因为在 Stage 的 Draggable 用 mousedown 处理了
      // 这里就不用处理 click 事件了
      // // 如果是拖拽引起的，则无视
      // if (this.$maker.stageInDragging) {
      //   //console.log("Ignore in-dragging")
      //   return
      // }
      // // 如果已经选中了，也无视
      // if (this.isCurrent) {
      //   return
      // }
      // //console.log("StageBlock:OnClickTop", this.block.name, ctrlKey)
      // // 精确选定
      // if (ctrlKey) {
      //   this.OnDblClickTop()
      // }
      // // 默认选择父控件
      // else {
      //   let $ps = Ti.Dom.parentsUntil(this.$el, ".as-com-wrapper", {
      //     iteratee: $it => Ti.Dom.hasClass($it, "lvgl-maker-com-block"),
      //     includeSelf: true,
      //     includeStop: false,
      //     reverse: true
      //   })
      //   let $b = _.first($ps)
      //   let name = Ti.Dom.attr($b, "name")
      //   //console.log({ $ps, $b, name })
      //   this.$notify("select:block", { name, shift: shiftKey })
      // }
    },
    //--------------------------------------
    OnDblClickTop() {
      //console.log("OnDblClickTop", this.block.name)
      this.$notify("select:block", this.block)
    },
    //--------------------------------------
    genlBlockMeasure() {
      // 并未准备好
      if (
        isNaN(this.zoomScale)
        || !_.isElement(this.$el)
        || _.isEmpty(this.viewportRect)
        || _.isEmpty(this.block)) {
        return {
          style: { visibility: "hidden" }
        }
      }
      // 得到视口/父控件的真实宽高
      let conW, conH;
      if (this.$parent.myMea) {
        conW = this.$parent.myMea.relW
        conH = this.$parent.myMea.relH
      }
      if (isNaN(conW) || !conW) {
        conW = this.viewportRect.width * this.zoomScale
      }
      if (isNaN(conH) || !conH) {
        conH = this.viewportRect.height * this.zoomScale
      }

      // 得到控件区块属性
      let { align, current, x, y, width, height } = this.block;

      // 如果是当前块，可能会被拖拽
      if (current) {
        //console.log({ align, current, x, y, width, height })
        let { myX, myY, myWidth, myHeight } = this.$stage
        x = Ti.Util.fallback(myX, x)
        y = Ti.Util.fallback(myY, y)
        width = Ti.Util.fallback(myWidth, width)
        height = Ti.Util.fallback(myHeight, height)
      }

      // 准备计算样式
      let relW = width * this.zoomScale;
      let relH = height * this.zoomScale;
      let css = { width: relW, height: relH, left: 0, top: 0 }

      // 得到布局计算函数
      let layoutFn = ({
        "CENTER": () => {
          css.left = (conW - relW) / 2
          css.top = (conH - relH) / 2
        },
        "IN_TOP_LEFT": () => {
          css.left = 0;
          css.top = 0
        },
        "IN_TOP_MID": () => {
          css.left = (conW - relW) / 2;
          css.top = 0
        },
        "IN_TOP_RIGHT": () => {
          css.left = conW - relW;
          css.top = 0
        },
        "IN_BOTTOM_LEFT": () => {
          css.left = 0;
          css.top = conH - relH
        },
        "IN_BOTTOM_MID": () => {
          css.left = (conW - relW) / 2;
          css.top = conH - relH
        },
        "IN_BOTTOM_RIGHT": () => {
          css.left = conW - relW;
          css.top = conH - relH
        },
        "IN_LEFT_MID": () => {
          css.left = 0;
          css.top = (conH - relH) / 2
        },
        "IN_RIGHT_MID": () => {
          css.left = conW - relW;
          css.top = (conH - relH) / 2
        },
        "OUT_TOP_LEFT": () => {
          css.left = 0;
          css.top = relH * -1
        },
        "OUT_TOP_MID": () => {
          css.left = (conW - relW) / 2;
          css.top = relH * -1
        },
        "OUT_TOP_RIGHT": () => {
          css.left = conW - relW;
          css.top = relH * -1
        },
        "OUT_BOTTOM_LEFT": () => {
          css.left = 0;
          css.top = conH;
        },
        "OUT_BOTTOM_MID": () => {
          css.left = (conW - relW) / 2;
          css.top = conH;
        },
        "OUT_BOTTOM_RIGHT": () => {
          css.left = conW - relW;
          css.top = conH;
        },
        "OUT_LEFT_TOP": () => {
          css.left = relW * -1;
          css.top = 0
        },
        "OUT_LEFT_MID": () => {
          css.left = relW * -1;
          css.top = (conH - relH) / 2
        },
        "OUT_LEFT_BOTTOM": () => {
          css.left = relW * -1;
          css.top = conH - relH;
        },
        "OUT_RIGHT_TOP": () => {
          css.left = conW;
          css.top = 0
        },
        "OUT_RIGHT_MID": () => {
          css.left = conW;
          css.top = (conH - relH) / 2
        },
        "OUT_RIGHT_BOTTOM": () => {
          css.left = conW;
          css.top = conH - relH;
        }
      })[align]

      // 执行布局计算: 自动计算中心点
      if (layoutFn) {
        // 如果需要布局计算，并且 width/height 取不到值
        // 那么就表示这个控件可能宽度，可能是高度，或者宽度和高度是自动计算的
        // 所以，我们这里应该搞一个 CSS 让它自由计算一下，然后再取其真实宽高
        if (isNaN(width) || isNaN(height)) {
          this.myMea = { style: {} }

          // 之后重新计算真实的宽高
          let res = this.$el.getBoundingClientRect()
          relW = res.width
          relH = res.height
        }
        // 这样才能进行布局计算
        layoutFn()
      }

      // 位移被父元素接管
      if (this.hasParentLayout) {
        delete css.left
        delete css.top
      }
      // 根据中心点增加偏移
      else {
        css.left += x * this.zoomScale
        css.top += y * this.zoomScale
      }

      // 根据缩放比例，调整一下宽高
      if (this.block.isAutoResize) {
        delete css.width
        delete css.height
      }
      // 并不是同时 resize 两个
      else if (!(this.block.isEWResize && this.block.isNSResize)) {
        // 仅仅缩放宽度
        if (this.block.isEWResize) {
          delete css.height
        }
        // 仅仅缩放高度
        else if (this.block.isNSResize) {
          delete css.width
        }
      }


      // 搞定
      return {
        width, height,
        relW, relH,
        conW, conH,
        style: Ti.Css.toStyle(css, { autoPercent: false })
      }
    },
    //--------------------------------------
    evalMyMeasure() {
      //console.log(_.get(this.block, "name"), "evalMyMeasure", this.viewportRect, this.zoomScale)
      this.myMea = this.genlBlockMeasure()
    },
    //--------------------------------------
    tryEvalMyMeasure(newVal, oldVal) {
      //console.log(`tryEvalMyMeasure(${newVal}, ${oldVal})`)
      if (!_.isEqual(newVal, oldVal)) {
        this.evalMyMeasure()
      }
    },
    //--------------------------------------
    tryEvalMyMeasureIfCurrent(forceUpdateChildren = false) {
      if (this.block && this.block.current) {
        // 更新自己
        this.evalMyMeasure()
        // 更新子孙
        if (forceUpdateChildren) {
          this.forceEvalChildrenMeasure()
        }
      }
    },
    //--------------------------------------
    forceEvalChildrenMeasure() {
      this.evalMyMeasure()
      if (_.isArray(this.$children)) {
        for (let $child of this.$children) {
          if (_.isFunction($child.forceEvalChildrenMeasure)) {
            $child.evalMyMeasure()
            $child.forceEvalChildrenMeasure()
          }
        }
      }
    },
    //--------------------------------------
  },
  //////////////////////////////////////////
  watch: {
    "zoomScale": "tryEvalMyMeasure",
    "viewportRect": "tryEvalMyMeasure",
    "block": "tryEvalMyMeasure",
    "parentLayout": "tryEvalMyMeasure",
    "$stage.myX": function () {
      this.tryEvalMyMeasureIfCurrent(false)
    },
    "$stage.myY": function () {
      this.tryEvalMyMeasureIfCurrent(false)
    },
    "$stage.myWidth": function () {
      this.tryEvalMyMeasureIfCurrent(true)
    },
    "$stage.myHeight": function () {
      this.tryEvalMyMeasureIfCurrent(true)
    },
  },
  //////////////////////////////////////////
  mounted() {
    this.evalMyMeasure()
  }
  //////////////////////////////////////////
};
return _M;;
})()
// ============================================================
// EXPORT 'm-my-buildsrv.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['mod/buildsrv/m-my-buildsrv.mjs'] = (function(){
//////////////////////////////////////////////
function findIn(list = [], id) {
  if (!id) {
    return null
  }
  return _.find(list, li => li.id && li.id.endsWith(id))
}
//////////////////////////////////////////////
const _M = {
  ////////////////////////////////////////////
  mutations: {
    //----------------------------------------
    setBuildMetas(state, buildMetas = []) {
      let metas = []
      let fonts = []
      _.forEach(buildMetas, ({ nm, content }) => {
        // for fonts
        if ("fonts.meta.json" == nm) {
          fonts = _.get(content, "fonts") || []
        }
        // for chips
        else {
          metas.push({ nm, content })
        }
      })
      state.buildMetas = metas
      state.buildFonts = fonts
      //...................................
      // 这里创建字典，给界面用
      //...................................
      let dictName = "MinkeBuildFonts"
      if (!Ti.DictFactory.hasDict(dictName)) {
        // 字体字典
        Ti.DictFactory.CreateDict({
          data: fonts
        }, { name: dictName })

        // 字体类型动态字典
        Ti.DictFactory.CreateDynamicDict(({ name } = {}) => {
          let font = _.find(fonts, ({ value }) => name == value)
          let ftypes = _.get(font, "ftype") || []
          return Ti.DictFactory.CreateDict({ data: ftypes })
        }, "MinkeBuildFontTypes")
      }
    },
    //----------------------------------------
    setMyBuildList(state, buildList = []) {
      state.myBuildList = buildList
    },
    //----------------------------------------
    setCurrentBuildId(state, buildId) {
      state.currentBuildId = buildId
      state.currentBuild = findIn(state.myBuildList, buildId)
      // 记录到本地
      Ti.Storage.session.set("minke-build-shop-current-build", buildId)
    },
    //----------------------------------------
    setCurrentBuildConf(state, data = {}) {
      let json = data
      if (!_.isString(data)) {
        json = JSON.stringify(data, null, '   ')
      }
      state.currentBuildConf = json

      // 2022-05-19 wendal said:
      // 根据当前编译配置，计算一个预测的编译大小
      // 首先，我们要根据芯片类型，确定采用的配置文件
      if (json) {
        // 得到当前的配置信息: {chip,layout,component...}
        let conf = JSON.parse(json)
        //console.log(conf)
        let { chip, script } = conf
        // 防守一道
        if (!chip) {
          return
        }
        // 找到对应芯片类型的配置文件
        let chipMetaName = `${chip}.meta.json`;
        let chipMeta = _.find(state.buildMetas, ({ nm }) => nm == chipMetaName)
        if (!chipMeta) {
          return
        }
        let selectedCom = conf.component || {}
        let chipConf = _.get(chipMeta, "content.builder") || {}
        let avaComs = _.get(chipConf, "component") || {}
        // 得到一个基础的尺寸
        let buildSize = _.get(chipConf, "chip.layout.rom.rsize") || 0
        let buildMaxSize = _.get(chipConf, "chip.layout.rom.max") || 0
        // 如果有脚本区数据，且大于默认大小，那么还得减去多出来的部分
        if (script > 64) {
          buildMaxSize -= (script - 64) * 1024
        }
        //console.log(buildSize, avaComs)
        // 递归所有子组件，找到选择的组件
        if (!_.isEmpty(selectedCom) && !_.isEmpty(avaComs)) {
          Ti.Trees.walkDeep({ children: avaComs }, ({ name, node = {} }) => {
            //console.log(name, node.rsize)
            if (selectedCom[name] && node.rsize > 0) {
              buildSize += node.rsize
            }
          })
        }
        // 更新一下
        state.currentBuildSize = buildSize
        state.currentMaxBuildSize = buildMaxSize
      }
    },
    //----------------------------------------
    setCurrentBuildDataFile(state, data) {
      state.currentBuildDataFile = data
    },
    //----------------------------------------
    setCurrentBuildDest(state, data) {
      state.currentBuildDest = data
    },
    //----------------------------------------
    setCurrentBuildLog(state, data) {
      state.currentBuildLog = data
    },
    //----------------------------------------
    setCurrentBuildSize(state, size) {
      state.currentBuildSize = size
    },
    //----------------------------------------
    setCurrentBuildMaxSize(state, maxSize) {
      state.currentMaxBuildSize = maxSize
    },
    //----------------------------------------
    setCurrentBuildSavedConf(state, data) {
      state.__saved_currentBuildConf = data
    },
    //----------------------------------------
    syncStatusChanged(state) {
      if (Ti.Util.isNil(state.currentBuildConf)
        && Ti.Util.isNil(state.__saved_currentBuildConf)) {
        state.status.changed = false
      } else {
        state.status.changed = !_.isEqual(
          state.currentBuildConf, state.__saved_currentBuildConf)
      }
    },
    //----------------------------------------
    setStatus(state, status) {
      state.status = _.assign({}, state.status, status)
    },
    //----------------------------------------
  }
  ////////////////////////////////////////////
}
return _M;;
})()
// ============================================================
// EXPORT 'lvgl-maker-style-text.mjs' -> null
// ============================================================
window.TI_PACK_EXPORTS['com/lvgl/maker/style/text/lvgl-maker-style-text.mjs'] = (function(){
////////////////////////////////////////////////////////
// 黑体：SimHei
// 宋体：SimSun
// 新宋体：NSimSun
// 仿宋：FangSong
// 仿宋_GB2312：FangSong_GB2312
// 楷体_GB2312：KaiTi_GB2312
// 楷体：KaiTi
// 微软正黑：Microsoft JhengHei
// 微软雅黑：Microsoft YaHei
// 细明体：MingLiU
// 标楷体：DFKai-SB
// 新细明体：PMingLiU
const _M = {
  //////////////////////////////////////////////////////
  props: {
    //-----------------------------------
    // Data
    //-----------------------------------
    value: {
      type: Object,
    },
  },
  //////////////////////////////////////////////////////
  computed: {
    //--------------------------------------------------
    StyleForm() {
      return {
        spacing: "comfy",
        linkFields: {
          "font.name": {
            test: {
              $update: {
                value: "SimSun",
              },
            },
            target: {
              font: {
                size: 16,
                weight: "NORMAL",
                name: "SimSun",
              },
            },
          },
        },
        fields: [
          {
            title: "文本颜色",
            name: "color",
            comType: "TiInputColor",
            comConf: {
              showAlpha: false,
            },
          },
          {
            title: "不透明度",
            name: "opa",
            type: "Integer",
            defaultAs: 255,
            comType: "TiInputNum",
            comConf: {
              step: 1,
              minValue: 0,
              maxValue: 255,
            },
          },
          {
            title: "字体",
            name: "font.name",
            defaultAs: "SimSun",
            comType: "TiSwitcher",
            comConf: {
              allowEmpty: false,
              options: [
                {
                  value: "SimSun",
                  text: "宋体",
                },
                {
                  value: "SimHei",
                  text: "黑体",
                },
              ],
            },
          },
          {
            title: "字号",
            name: "font.size",
            type: "Integer",
            defaultAs: 16,
            tip: "范围 16-96，仅支持设置偶数",
            visible: {
              "font.name": "SimHei",
            },
            comType: "TiInputNum",
            comConf: {
              step: 2,
              minValue: 16,
              maxValue: 96,
            },
          },
          {
            title: "字号",
            name: "font.size",
            defaultAs: 16,
            type: "Integer",
            hidden: {
              "font.name": "SimHei",
            },
          },
          {
            title: "粗细度",
            name: "font.weight",
            defaultAs: "NORMAL",
            comType: "TiSwitcher",
            visible: {
              "font.name": "SimHei",
            },
            comConf: {
              options: [
                {
                  value: "LIGHT",
                  text: "细",
                },
                {
                  value: "NORMAL",
                  text: "常规",
                },
                {
                  value: "HEAVY",
                  text: "粗",
                },
              ],
            },
          },
          {
            title: "粗细度",
            name: "font.weight",
            defaultAs: "NORMAL",
            hidden: {
              "font.name": "SimHei",
            },
            comType: "TiLabel",
            comConf: {
              format: (v) => {
                return {
                  LIGHT: "细",
                  NORMAL: "常规",
                  HEAVY: "粗",
                }[v || "NORMAL"];
              },
            },
          },
          {
            title: "字间距",
            name: "letterSpace",
            type: "Integer",
            comType: "TiInput",
          },
          {
            title: "行间距",
            name: "lineSpace",
            type: "Integer",
            comType: "TiInput",
          },
          {
            title: "修饰符",
            name: "decor",
            comType: "TiDroplist",
            comConf: {
              options: ["NONE", "UNDERLINE", "STRIKETHROUGH"],
            },
          },
          {
            title: "选中文字",
            name: "selColor",
            comType: "TiInputColor",
            comConf: {
              showAlpha: false,
            },
          },
          {
            title: "选中背景",
            name: "selBgColor",
            comType: "TiInputColor",
            comConf: {
              showAlpha: false,
            },
          },
          {
            title: "混合模式",
            name: "blendMode",
            comType: "TiDroplist",
            comConf: {
              options: ["NORMAL", "ADDITIVE", "SUBTRACTIVE"],
            },
          },
        ],
      };
    },
    //--------------------------------------------------
  },
  //////////////////////////////////////////////////////
};
return _M;;
})()
})();   // ~ windows.TI_EXPORTS
(function(){
//========================================
// JOIN <buildshop.html> com/buildshop/buildshop.html
//========================================
Ti.Preload("com/buildshop/buildshop.html", `<TiGui
  class="luo-buildshop"
  :layout="TheLayout"
  :schema="TheSchema"
  :loading="isLoading"
  :canLoading="true"/>`);
//========================================
// JOIN <buildshop.mjs> com/buildshop/buildshop.mjs
//========================================
Ti.Preload("com/buildshop/buildshop.mjs", TI_PACK_EXPORTS['com/buildshop/buildshop.mjs']);
//========================================
// JOIN <build-editconf.html> com/buildshop/editconf/build-editconf.html
//========================================
Ti.Preload("com/buildshop/editconf/build-editconf.html", `<TiGui
  class="luo-build-editconf"
  :layout="TheLayout"
  :schema="TheSchema"
  @form::change="OnFormChange"
  @form::field:change="OnFormFieldChange"/>`);
//========================================
// JOIN <build-editconf.mjs> com/buildshop/editconf/build-editconf.mjs
//========================================
Ti.Preload("com/buildshop/editconf/build-editconf.mjs", TI_PACK_EXPORTS['com/buildshop/editconf/build-editconf.mjs']);
//========================================
// JOIN <build-fonts.mjs> com/buildshop/editconf/build-fonts.mjs
//========================================
Ti.Preload("com/buildshop/editconf/build-fonts.mjs", TI_PACK_EXPORTS['com/buildshop/editconf/build-fonts.mjs']);
//========================================
// JOIN <_com.json> com/buildshop/editconf/_com.json
//========================================
Ti.Preload("com/buildshop/editconf/_com.json", {
  "name": "luo-build-editconf",
  "globally": true,
  "template": "./build-editconf.html",
  "mixins": [
    "./build-editconf.mjs",
    "./build-fonts.mjs"
  ],
  "components": [
    "@com:ti/slide/stack",
    "@com:web/upload/file"
  ]
});
//========================================
// JOIN <build-result.html> com/buildshop/result/build-result.html
//========================================
Ti.Preload("com/buildshop/result/build-result.html", `<div class="luo-build-result">
  <table>
    <!--
      显示状态
    -->
    <tr class="as-status">
      <td>构建状态</td>
      <td>
        <span>{{BuildStatusText}}</span>
      </td>
    </tr>
    <!--
      构建大小
    -->
    <tr class="as-build-size" v-if="hasBuildSize">
      <td>预计大小</td>
      <td>
        <div class="as-bar" :class="BuildSizeBarClass">
          <div class="as-bar-outer">
            <div
              class="as-bar-inner" 
              :style="BuildSizeBarInnerStyle">
                <span>{{BuildSizeText}}</span>
            </div>
          </div>
          <div class="as-bar-tip">
            <span>{{MaxBuildSizeText}}</span>
          </div>
        </div>
        <div class="as-warn-tip" v-if="isBuildOverSize">
          <i class="zmdi zmdi-alert-polygon"></i>
          <span>您选择的组件，超过了最大容量</span>
        </div>
      </td>
    </tr>
    <!--
      构建时间
    -->
    <tr class="as-timestamp is-start-at" v-if="BuildStatus > 0">
      <td>开始时间</td><td>{{BuildStartAt}}</td>
    </tr>
    <tr class="as-timestamp is-done-at" v-if="BuildStatus > 0">
      <td>结束时间</td><td>{{BuildDoneAt}}</td>
    </tr>
    <!--
      构建下载
    -->
    <tr class="as-dest" v-if="BuildStatus == 10 && hasData">
      <td>构建结果</td>
      <td>
        <a :href="BuildDestDownloadUrl">
          <i class="fas fa-file-archive"></i>
          <span>下载构建结果</span>
        </a>
      </td>
    </tr>
    <!--
      日志下载
    -->
    <tr class="as-dest" v-if="hasBuildLog">
      <td>构建日志</td>
      <td>
        <a :href="BuildLogDownloadUrl">
          <i class="far fa-file-alt"></i>
          <span>下载构建日志</span>
        </a>
      </td>
    </tr>
  </table>
  <div class="as-actions">
    <TiButton :setup="ActionBtnSetup"/>
  </div>
</div>`);
//========================================
// JOIN <build-result.mjs> com/buildshop/result/build-result.mjs
//========================================
Ti.Preload("com/buildshop/result/build-result.mjs", TI_PACK_EXPORTS['com/buildshop/result/build-result.mjs']);
//========================================
// JOIN <_com.json> com/buildshop/result/_com.json
//========================================
Ti.Preload("com/buildshop/result/_com.json", {
  "name" : "luo-build-result",
  "globally" : true,
  "inject": {
    "apiBase" : {"default" : "/api"},
    "cdnTmpl" : {"default" : null}, 
    "base"    : {"default" : "/"}
  },
  "template" : "./build-result.html",
  "mixins" : "./build-result.mjs"
});
//========================================
// JOIN <_com.json> com/buildshop/_com.json
//========================================
Ti.Preload("com/buildshop/_com.json", {
  "name" : "luo-buildshop",
  "globally" : true,
  "inject": {
    "apiBase" : {"default" : "/api"},
    "cdnTmpl" : {"default" : null}, 
    "base"    : {"default" : "/"}
  },
  "template" : "./buildshop.html",
  "mixins" : "./buildshop.mjs",
  "components": [
    "./editconf",
    "./result"
  ]
});
//========================================
// JOIN <devdetail.html> com/devdetail/devdetail.html
//========================================
Ti.Preload("com/devdetail/devdetail.html", `<div class="luo-devdetail"
  :class="TopClass"> 
  <!--
    显示操作菜单
  -->
  <!--
    显示地图
  -->
  <WebGisLeaflet
    class="ti-fill-parent"
    :value="DevGisData"
    keep-zoom-by="luo-dev-geo-zoom"
    value-type="obj-list"
    display-type="Cluster"
    marker-icon="png/map-pin-3.png"
    :marker-icon-options="{iconSize:[41,41], iconAnchor:[20,41]}"
    :marker-popup="DevMarkerPopup"
    :marker-popup-options="DevMarkerPopupOptions"
    :show-info="{zoom:true,pointerHover:true,pointerClick:true}"/>
</div>`);
//========================================
// JOIN <devdetail.mjs> com/devdetail/devdetail.mjs
//========================================
Ti.Preload("com/devdetail/devdetail.mjs", TI_PACK_EXPORTS['com/devdetail/devdetail.mjs']);
//========================================
// JOIN <_com.json> com/devdetail/_com.json
//========================================
Ti.Preload("com/devdetail/_com.json", {
  "name" : "luo-devdetail",
  "globally" : true,
  "inject": {
    "apiBase" : {"default" : "/api"},
    "cdnTmpl" : {"default" : null}, 
    "base"    : {"default" : "/"}
  },
  "template" : "./devdetail.html",
  "mixins" : ["./devdetail.mjs"]
});
//========================================
// JOIN <change-log.json> com/lvgl/change-log.json
//========================================
Ti.Preload("com/lvgl/change-log.json", {
  "history": [
    {
      "date": "2022-07-21",
      "content": [
        "【新增】设备背景设置",
        "【更新】日历支持设置显示日期和当前的日期（今日）",
        "【更新】日历日期外观属性名称",
        "【修正】今日样式覆盖高亮样式bug"
      ]
    },
    {
      "date": "2022-07-14",
      "content": [
        "【修正】日历控件显示名称和icon",
        "【优化】日历控件高亮日期控件",
        "【优化】日历控件部分属性tip显示方式",
        "【修正】日历控件标题设置颜色",
        "【修正】日历控件日期默认样式",
        "【修正】字体默认宋体设置项显示问题"
      ]
    },
    {
      "date": "2022-07-08",
      "content": [
        "【新增】画布>面包屑指示条",
        "【新增】画布>控件多选指示器",
        "【新增】画布>控件支持 shift 多选",
        "【新增】画布>控件支持 shift+ctrl 多选子控件",
        "【新增】控件大纲支持显示多选控件",
        "【优化】控件的选中消除重复事件，提高效率",
        "【优化】更高效紧凑的属性面板",
        "【更新】日历今日字段调整",
        "【新增】日历高亮配置项与对应显示效果",
        "【更新】日历支持配置背景颜色",
        "【更新】日历支持配置头部文字样式",
        "【更新】日历支持配置标题文字样式",
        "【更新】日历支持配置日期四种文字样式",
        "【新增】图片按钮图片支持“选中按下”和“选中抬起”",
        "【新增】图片按钮支持设置自动切换选中",
        "【新增】按钮增加 CHECKED 状态"
      ]
    },
    {
      "date": "2022-07-01",
      "content": [
        "【更新】日历控件显示真实日期",
        "【更新】日历控件今日显示效果",
        "【更新】日历控件自定义星期名",
        "【更新】日历控件自定义月份名"
      ]
    },
    {
      "date": "2022-06-24",
      "content": [
        "【修正】重新加载，会导致图片重新恢复原始大小的问题",
        "【修正】图表缩小时显示样式错误的问题",
        "【优化】设计区域背景色与部分控件默认背景色无法区分的问题",
        "【新增】日历控件占位（对接部分属性）"
      ]
    },
    {
      "date": "2022-06-22",
      "content": [
        "【修正】图片按钮给入多个图片，按钮被重置为原始尺寸的问题",
        "【新增】cont 控件支持设置边框属性",
        "【新增】page 控件",
        "【新增】图表控件增加边框",
        "【修正】图表控件边距设置优化，更符合模拟器效果"
      ]
    },
    {
      "date": "2022-06-17",
      "content": [
        "【修正】容器cont支持 FIT_MAX 显示问题",
        "【修正】属性面板的外观宽高总是显示`自动`问题",
        "【修正】多层嵌套控件，修改尺寸失效"
      ]
    },
    {
      "date": "2022-06-15",
      "content": [
        "【优化】Lvgl.resources的引用，不再有控件引用时自动删除",
        "【更新】容器cont支持 FIT_TIGHT/FIT_PARENT/FIT_MAX",
        "【更新】容器cont支持互相嵌套",
        "【更新】图表x轴刻度样式支持2种模式",
        "【更新】图表y轴刻度样式支持3种模式"
      ]
    },
    {
      "date": "2022-06-10",
      "content": [
        "【新增】图表样式支持柱状图",
        "【新增】图表数据支持设置起始下标",
        "【新增】图表支持设置显示点数，并与数据列表与起始下标进行联动",
        "【新增】图表增加数据刷新时长",
        "【优化】部分控件的文字提示内容"
      ]
    },
    {
      "date": "2022-06-06",
      "content": [
        "【更新】容器cont自动填充属性支持了FIT_NONE",
        "【优化】按钮尝试兼容老版本代码",
        "【优化】选择框尝试兼容老版本代码",
        "【优化】选择框checked，disabled属性显示问题"
      ]
    },
    {
      "date": "2022-06-02",
      "content": [
        "【修正】按钮与图片按钮状态再调整",
        "【修正】按钮文字居中且不换行",
        "【修正】按钮状态设置",
        "【修正】按钮启动切换状态设置",
        "【修正】选择框选中跟禁止状态应该只能二选一",
        "【修正】虚拟键盘增加默认字体",
        "【修正】Switch圆圈高度计算错误",
        "【新增】设计器缩放比例提示信息",
        "【修正】涉及文字控件（Label,Button,Textarea,DropdownList,Keyboard,Checkbox）都会根据比例进行正确的缩放",
        "【修正】chart超出边框部分显示问题"
      ]
    },
    {
      "date": "2022-05-27",
      "content": [
        "【增加】布局容器控件",
        "【修正】选择框文字不能设置大小的问题",
        "【修正】按钮与图片按钮状态统一为三种，去掉冗余状态",
        "【修正】控件菜单与图表属性部分文字",
        "【增加】图表背景样式对接（颜色，透明度，渐变）",
        "【增加】图表刻度线样式对接（宽度，颜色，透明度）",
        "【增加】图表刻度文字样式对接（大小，颜色）",
        "【增加】图表边距样式对接（内边距）",
        "【增加】图表X轴刻度线",
        "【增加】图表Y轴刻度线"
      ]
    },
    {
      "date": "2022-05-20",
      "content": [
        "【修正】图表分割线计算错误问题",
        "【修正】图表Y值区间参数",
        "【增加】图表更新模式设置",
        "【增加】图表Y轴刻度相关参数设置",
        "【增加】图表X轴刻度相关参数设置"
      ]
    },
    {
      "date": "2022-05-18",
      "content": [
        "【新增】图表控件",
        "【新增】图表支持隐藏类型",
        "【新增】图表支持折线图类型",
        "【新增】图表支持设置Y值区间",
        "【新增】图表支持设置分割线",
        "【新增】图表支持任意缩放"
      ]
    },
    {
      "date": "2022-05-13",
      "content": [
        "【修正】仪表盘表盘参数配置",
        "【修正】仪表盘指针角度错误",
        "【修正】仪表盘整体旋转角度错误",
        "【修正】仪表盘临界值显示错误",
        "【优化】选择框改为根据内容自动扩展大小",
        "【修正】选择框背景样式与模拟器不一致问题",
        "【新增】虚拟键盘与文本输入框关联隐藏属性开关"
      ]
    },
    {
      "date": "2022-05-11",
      "content": ["【新增】仪表盘控件", "【新增】设计器更新记录"]
    },
    {
      "date": "2022-04-30",
      "content": [
        "【新增】组件大纲支持了嵌套功能",
        "【新增】二维码控件",
        "【修正】下拉框宽度调节w问题"
      ]
    },
    {
      "date": "2022-04-27",
      "content": [
        "【优化】控件选择页面进行了功能性分组",
        "【优化】弧控件增加了边框0的默认值"
      ]
    }
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/arc/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/arc/hmaker.json", {
  "icon": "fas-circle-notch",
  "title": "弧",
  "forceRatio": true,
  "measure": {
    "width": 100,
    "height": 100
  },
  "defaultPart": "BG",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "value": 50,
    "range": [0, 100],
    "bgStartAngle": 120,
    "bgEndAngle": 60,
    "rotation": 0,
    "adjustable": false,
    "defaultStatus": {
      "bgPart": {
        "border": {
          "width": 0
        }
      },
      "indicPart": {},
      "knobPart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景弧"
    },
    {
      "value": "INDIC",
      "text": "指示弧"
    },
    {
      "value": "KNOB",
      "text": "控制柄"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "线属性",
      "name": "partStyle.line",
      "type": "Object",
      "comType": "LvglMakerStyleLine"
    }
  ],
  "indicPartFields": [
    {
      "title": "线属性",
      "name": "partStyle.line",
      "type": "Object",
      "comType": "LvglMakerStyleLine"
    }
  ],
  "knobPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "propFields": [
    {
      "title": "外观类型",
      "name": "type",
      "defaultAs": "ARC_TYPE_NORMAL",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "value": "ARC_TYPE_NORMAL",
            "text": "正向弧"
          },
          {
            "value": "ARC_TYPE_REVERSE",
            "text": "反向弧"
          },
          {
            "value": "ARC_TYPE_SYMMETRIC",
            "text": "对称弧"
          }
        ]
      }
    },
    {
      "title": "数据"
    },
    {
      "title": "当前值",
      "name": "value",
      "tip": "输入一个最小值和最大值之间的整数",
      "type": "Integer",
      "comConf": {
        "range": "=item.range"
      }
    },
    {
      "title": "值区间",
      "name": "range",
      "tip": "最小值和最大值，中间用半角逗号分隔",
      "type": "Array",
      "width": 120,
      "serializer": "Minke.rangeToArray",
      "comConf": {
        "placeholder": "0,100"
      }
    },
    {
      "title": "整体旋转",
      "name": "rotation",
      "tip": "角度值: 0-360",
      "type": "Integer",
      "defaultAs": 0
    },
    {
      "title": "背景弧"
    },
    {
      "title": "开始角度",
      "name": "bgStartAngle",
      "tip": "角度值: 0-360",
      "type": "Integer"
    },
    {
      "title": "结束角度",
      "name": "bgEndAngle",
      "tip": "角度值: 0-360",
      "type": "Integer"
    },
    {
      "title": "控制柄显示",
      "name": "adjustable",
      "type": "Boolean",
      "comType": "TiToggle"
    }
  ],
  "comEvents": ["#GENERIC_EVENTS", "VALUE_CHANGED"]
});
//========================================
// JOIN <lvgl-arc.html> com/lvgl/core/arc/lvgl-arc.html
//========================================
Ti.Preload("com/lvgl/core/arc/lvgl-arc.html", `<div class="lvgl-com-arc" :class="TopClass">
  <div class="arc-container" :style="arcBgStyle">
    <svg class="arc-bg" width="200" height="200" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"
      :style="bgStyle">
      <!-- 进度条 -->
      <circle class="arc-line" :r="lineR" :cx="lineX" :cy="lineY" fill="transparent" :style="lineStyle"></circle>
      <!-- 进度indic -->
      <circle class="arc-indic" :r="indicR" :cx="indicX" :cy="indicY" fill="transparent" :style="indicStyle">
      </circle>
      <!-- 控制小球knob -->
      <circle class="arc-knob" :r="indicR" :cx="indicX" :cy="indicY" fill="transparent" :style="knobStyle">
      </circle>
    </svg>
  </div>
</div>`);
//========================================
// JOIN <lvgl-arc.mjs> com/lvgl/core/arc/lvgl-arc.mjs
//========================================
Ti.Preload("com/lvgl/core/arc/lvgl-arc.mjs", TI_PACK_EXPORTS['com/lvgl/core/arc/lvgl-arc.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/arc/_com.json
//========================================
Ti.Preload("com/lvgl/core/arc/_com.json", {
  "name": "LvglArc",
  "globally": true,
  "template": "./lvgl-arc.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-arc.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/bar/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/bar/hmaker.json", {
  "icon": "zmdi-ruler",
  "title": "进度条",
  "measure": {
    "width": 200,
    "height": 20
  },
  "defaultPart": "BG",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "startValue": [50, "ANIM_OFF"],
    "value": [50, "ANIM_OFF"],
    "range": [0, 100],
    "defaultStatus": {
      "bgPart": {},
      "indicPart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景条"
    },
    {
      "value": "INDIC",
      "text": "指示条"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    }
  ],
  "indicPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "propFields": [
    {
      "title": "外观类型",
      "name": "type",
      "defaultAs": "BAR_TYPE_NORMAL",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "value": "BAR_TYPE_NORMAL",
            "text": "普通"
          },
          {
            "value": "BAR_TYPE_SYMMETRICAL",
            "text": "对称"
          },
          {
            "value": "BAR_TYPE_CUSTOM",
            "text": "自定义"
          }
        ]
      }
    },
    {
      "title": "数据"
    },
    {
      "title": "开始值",
      "name": "startValue",
      "tip": "输入一个最小值和最大值之间的整数",
      "type": "Array",
      "comType": "LvglMakerFormAnimatVal",
      "comConf": {
        "range": "=item.range"
      }
    },
    {
      "title": "当前值",
      "name": "value",
      "tip": "输入一个最小值和最大值之间的整数",
      "type": "Array",
      "comType": "LvglMakerFormAnimatVal",
      "comConf": {
        "range": "=item.range"
      }
    },
    {
      "title": "值区间",
      "name": "range",
      "tip": "最小值和最大值，中间用半角逗号分隔",
      "type": "Array",
      "width": 120,
      "serializer": "Minke.rangeToArray",
      "comConf": {
        "placeholder": "0,100"
      }
    },
    {
      "title": "动画时长",
      "name": "animTime",
      "type": "Integer",
      "width": 120,
      "comType": "TiInput",
      "comConf": {
        "suffixText": "ms"
      }
    }
  ],
  "comEvents": ["#GENERIC_EVENTS"]
});
//========================================
// JOIN <lvgl-bar.html> com/lvgl/core/bar/lvgl-bar.html
//========================================
Ti.Preload("com/lvgl/core/bar/lvgl-bar.html", `<div class="lvgl-com-bar lvgl-inner-com-slider" :class="TopClass">
  <div class="part-bg" :style="PartBgStyle">
    <div class="part-indic" :style="PartIndicStyle"></div>
  </div>
</div>`);
//========================================
// JOIN <lvgl-bar.mjs> com/lvgl/core/bar/lvgl-bar.mjs
//========================================
Ti.Preload("com/lvgl/core/bar/lvgl-bar.mjs", TI_PACK_EXPORTS['com/lvgl/core/bar/lvgl-bar.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/bar/_com.json
//========================================
Ti.Preload("com/lvgl/core/bar/_com.json", {
  "name": "LvglBar",
  "globally": true,
  "template": "./lvgl-bar.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-bar.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/btnmatrix/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/btnmatrix/hmaker.json", {
  "icon": "zmdi-view-comfy",
  "title": "按钮矩阵",
  "measure": {
    "width": 300,
    "height": 160
  },
  "defaultPart": "BG",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "defaultStatus": {
      "defaultStatus": {
        "bgPart": {},
        "btnPart": {}
      }
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景条"
    },
    {
      "value": "BTN",
      "text": "按钮"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "btnPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "propFields": [
    {
      "title": "按钮文字",
      "name": "map",
      "type": "Array",
      "comType": "TiInputText"
    },
    {
      "title": "按钮宽度",
      "name": "btnWidth",
      "type": "Integer",
      "comType": "TiInputNum"
    },
    {
      "title": "按钮文字",
      "name": "align",
      "type": "String",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "icon": "fas-align-left",
            "value": "LEFT",
            "tip": "居左"
          },
          {
            "icon": "fas-align-center",
            "value": "CENTER",
            "tip": "居中"
          },
          {
            "icon": "fas-align-right",
            "value": "RIGHT",
            "tip": "居右"
          }
        ]
      }
    },
    {
      "title": "指定颜色",
      "name": "recolor",
      "type": "Boolean",
      "comType": "TiToggle"
    }
  ],
  "comEvents": [
    "#GENERIC_EVENTS",
    "VALUE_CHANGED"
  ]
});
//========================================
// JOIN <lvgl-btnmatrix.html> com/lvgl/core/btnmatrix/lvgl-btnmatrix.html
//========================================
Ti.Preload("com/lvgl/core/btnmatrix/lvgl-btnmatrix.html", `<div class="lvgl-com-btnmatrix" :class="TopClass"> 
  
</div>`);
//========================================
// JOIN <lvgl-btnmatrix.mjs> com/lvgl/core/btnmatrix/lvgl-btnmatrix.mjs
//========================================
Ti.Preload("com/lvgl/core/btnmatrix/lvgl-btnmatrix.mjs", TI_PACK_EXPORTS['com/lvgl/core/btnmatrix/lvgl-btnmatrix.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/btnmatrix/_com.json
//========================================
Ti.Preload("com/lvgl/core/btnmatrix/_com.json", {
  "name": "LvglBtnMatrix",
  "globally": true,
  "template": "./lvgl-btnmatrix.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-btnmatrix.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/button/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/button/hmaker.json", {
  "icon": "fas-hand-point-up",
  "title": "按钮",
  "defaultPart": "MAIN",
  "defaultStatus": "DEFAULT",
  "measure": {
    "width": 100,
    "height": 30
  },
  "comConf": {
    "text": "新按钮",
    "state": "BTN_STATE_RELEASED",
    "defaultStatus": {
      "mainPart": {
        "radius": 8,
        "bg": {
          "color": "#0088FF"
        },
        "text": {
          "font": {
            "name": "SimSun",
            "size": 16,
            "weight": "NORMAL"
          },
          "color": "#FFFFFF"
        }
      }
    }
  },
  "comTransition": true,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    },
    {
      "value": "PRESSED",
      "text": "按下"
    },
    {
      "value": "DISABLED",
      "text": "禁止"
    },
    {
      "value": "CHECKED",
      "text": "选中"
    }
  ],
  "comParts": [
    {
      "value": "MAIN",
      "text": "主区域"
    }
  ],
  "mainPartFields": [
    {
      "title": "文字样式",
      "name": "partStyle.text",
      "type": "Object",
      "comType": "LvglMakerStyleText",
      "visible": {
        "status": "DEFAULT"
      }
    },
    {
      "title": "背景",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "边框",
      "name": "partStyle.border",
      "type": "Object",
      "comType": "LvglMakerStyleBorder"
    },
    {
      "title": "轮廓",
      "name": "partStyle.outline",
      "type": "Object",
      "comType": "LvglMakerStyleOutline"
    },
    {
      "title": "阴影",
      "name": "partStyle.shadow",
      "type": "Object",
      "comType": "LvglMakerStyleShadow"
    },
    {
      "title": "圆角",
      "name": "partStyle.radius",
      "type": "Integer",
      "comType": "TiInputNum",
      "comConf": {
        "placeholder": 0,
        "step": 1,
        "minValue": 0
      }
    }
  ],
  "propFields": [
    {
      "title": "状态",
      "name": "state",
      "defaultAs": "BTN_STATE_RELEASED",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "value": "BTN_STATE_RELEASED",
            "text": "默认"
          },
          {
            "value": "BTN_STATE_PRESSED",
            "text": "按下"
          },
          {
            "value": "BTN_STATE_DISABLED",
            "text": "禁止"
          }
        ]
      }
    },
    {
      "title": "自动切换状态",
      "width": "1.4rem",
      "name": "checkable",
      "type": "Boolean",
      "comType": "TiToggle"
    },
    {
      "title": "文字内容",
      "name": "text",
      "nameVAlign": "top",
      "comType": "TiInputText"
    }
  ],
  "comEvents": [
    "#GENERIC_EVENTS",
    "VALUE_CHANGED"
  ]
});
//========================================
// JOIN <lvgl-button.html> com/lvgl/core/button/lvgl-button.html
//========================================
Ti.Preload("com/lvgl/core/button/lvgl-button.html", `<div class="lvgl-com-button" :class="TopClass" :style="TopStyle">
  <div class="part-main" :style="PartMainStyle">
    <div class="part-text" :style="PartTextStyle">
      <p class="button-text" v-html="ValueHtml"></p>
    </div>
  </div>
</div>`);
//========================================
// JOIN <lvgl-button.mjs> com/lvgl/core/button/lvgl-button.mjs
//========================================
Ti.Preload("com/lvgl/core/button/lvgl-button.mjs", TI_PACK_EXPORTS['com/lvgl/core/button/lvgl-button.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/button/_com.json
//========================================
Ti.Preload("com/lvgl/core/button/_com.json", {
  "name": "LvglButton",
  "globally": true,
  "template": "./lvgl-button.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-button.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/calendar/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/calendar/hmaker.json", {
  "icon": "far-calendar-alt",
  "title": "日历",
  "measure": {
    "width": 160,
    "height": 160
  },
  "defaultPart": "BG",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "defaultStatus": {
      "bgPart": {},
      "headerPart": {},
      "dayNamesPart": {},
      "datePart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景"
    },
    {
      "value": "HEADER",
      "text": "头部"
    },
    {
      "value": "DAY_NAMES",
      "text": "标题"
    },
    {
      "value": "DATE",
      "text": "日期"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "headerPartFields": [
    {
      "title": "文字样式",
      "name": "partStyle.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    }
  ],
  "dayNamesPartFields": [
    {
      "title": "文字样式",
      "name": "partStyle.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    }
  ],
  "datePartFields": [
    {
      "title": "默认样式",
      "name": "partStyle.defaultStatus.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    },
    {
      "title": "按下样式",
      "name": "partStyle.pressedStatus.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    },
    {
      "title": "今日样式",
      "name": "partStyle.focusedStatus.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    },
    {
      "title": "高亮样式",
      "name": "partStyle.checkedStatus.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    }
  ],
  "propFields": [
    {
      "title": "当前的日期（今天）",
      "name": "todayDate",
      "comType": "TiInputDate"
    },
    {
      "title": "显示日期",
      "name": "showedDate",
      "comType": "TiInputDate"
    },
    {
      "title": "高亮日期",
      "name": "highlightedDates",
      "type": "Array",
      "nameVAlign": "top",
      "transformer": "Minke.arrayEleValToObj('date')",
      "serializer": "Minke.arrayEleObjToVal('date')",
      "comType": "TiComboTable",
      "comConf": {
        "newItemText": "添加日期",
        "blankAs": {
          "text": "并未设置任何日期"
        },
        "list": {
          "fields": [
            {
              "title": "日期",
              "display": "date"
            }
          ]
        },
        "dialog": {
          "title": "编辑日期",
          "width": "4.8rem",
          "height": "6.4rem"
        },
        "form": {
          "fields": [
            {
              "title": "日期",
              "name": "date",
              "nameWrap": "wrap",
              "nameAlign": "left",
              "comType": "TiInputDate",
              "comConf": {
                "width": "100%"
              }
            }
          ]
        }
      }
    },
    {
      "title": "星期名",
      "name": "dayNames",
      "type": "Array",
      "nameVAlign": "top",
      "comType": "TiInputText",
      "comConf": {
        "placeholder": "数量必须为七个，使用逗号分割"
      }
    },
    {
      "title": "月份名",
      "name": "monthNames",
      "type": "Array",
      "nameVAlign": "top",
      "comType": "TiInputText",
      "comConf": {
        "placeholder": "数量必须为十二个，使用逗号分割"
      }
    }
  ],
  "comEvents": ["#GENERIC_EVENTS", "VALUE_CHANGED"]
});
//========================================
// JOIN <lvgl-calendar.html> com/lvgl/core/calendar/lvgl-calendar.html
//========================================
Ti.Preload("com/lvgl/core/calendar/lvgl-calendar.html", `<div class="lvgl-com-calendar">
  <div class="cal-container" :style="calendarBgStyle">
    <div class="cal-header" :style="calendarHeaderStyle">
      <div class="cal-icon"><i class="fa fa-chevron-left"></i></div>
      <div class="cal-year">{{year}}</div>
      <div class="cal-month">{{monthText}}</div>
      <div class="cal-icon"><i class="fa fa-chevron-right"></i></div>
    </div>
    <div class="cal-names" :style="calendarNamesStyle">
      <div class="cal-week-name" v-for="wn in dayNamesText" :key='wn'>{{wn}}</div>
    </div>
    <div class="cal-dates">
      <div :class="calDateClz(di)" :style="calDateStyle(di)" v-for="di in dateGrid" :key="di.allDate">
        {{di.showDate}}
      </div>
    </div>
  </div>
</div>`);
//========================================
// JOIN <lvgl-calendar.mjs> com/lvgl/core/calendar/lvgl-calendar.mjs
//========================================
Ti.Preload("com/lvgl/core/calendar/lvgl-calendar.mjs", TI_PACK_EXPORTS['com/lvgl/core/calendar/lvgl-calendar.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/calendar/_com.json
//========================================
Ti.Preload("com/lvgl/core/calendar/_com.json", {
  "name": "LvglCalendar",
  "globally": true,
  "template": "./lvgl-calendar.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-calendar.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/cb/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/cb/hmaker.json", {
  "icon": "far-check-square",
  "title": "选择框",
  "defaultResizable": "auto",
  "measure": {},
  "defaultPart": "BG",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "text": "选择框文本",
    "checked": false,
    "disabled": false,
    "defaultStatus": {
      "bgPart": {
        "text": {
          "font": {
            "name": "SimSun",
            "size": 16,
            "weight": "NORMAL"
          }
        }
      },
      "bulletPart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    },
    {
      "value": "PRESSED",
      "text": "按下"
    },
    {
      "value": "DISABLED",
      "text": "禁止"
    },
    {
      "value": "CHECKED_RELEASED",
      "text": "选中抬起"
    },
    {
      "value": "CHECKED_PRESSED",
      "text": "选中按下"
    },
    {
      "value": "CHECKED_DISABLED",
      "text": "选中禁止"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景"
    },
    {
      "value": "BULLET",
      "text": "指示符"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "文字样式",
      "name": "partStyle.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    }
  ],
  "bulletPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "propFields": [
    {
      "title": "文本",
      "name": "text"
    },
    {
      "title": "选中",
      "name": "checked",
      "type": "Boolean",
      "disabled": {
        "disabled": true
      },
      "comType": "TiToggle"
    },
    {
      "title": "禁止",
      "name": "disabled",
      "type": "Boolean",
      "disabled": {
        "checked": true
      },
      "comType": "TiToggle"
    }
  ],
  "comEvents": [
    "#GENERIC_EVENTS",
    "VALUE_CHANGED"
  ]
});
//========================================
// JOIN <lvgl-checkbox.html> com/lvgl/core/cb/lvgl-checkbox.html
//========================================
Ti.Preload("com/lvgl/core/cb/lvgl-checkbox.html", `<div class="lvgl-com-checkbox" :class="TopClass">
  <!--选择指示器-->
  <div class="part-bullet" :style="BulletStyle">
    <i :class="BulletClass"></i>
  </div>
  <!--文本-->
  <div class="part-text" :style="BgStyle">{{text}}</div>
</div>`);
//========================================
// JOIN <lvgl-checkbox.mjs> com/lvgl/core/cb/lvgl-checkbox.mjs
//========================================
Ti.Preload("com/lvgl/core/cb/lvgl-checkbox.mjs", TI_PACK_EXPORTS['com/lvgl/core/cb/lvgl-checkbox.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/cb/_com.json
//========================================
Ti.Preload("com/lvgl/core/cb/_com.json", {
  "name": "LvglCheckbox",
  "globally": true,
  "template": "./lvgl-checkbox.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-checkbox.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/chart/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/chart/hmaker.json", {
  "icon": "fas-chart-line",
  "title": "图表",
  "measure": {
    "width": 225,
    "height": 150
  },
  "defaultPart": "BG",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "type": "CHART_TYPE_LINE",
    "series": [],
    "yRange": [0, 100],
    "divLineCount": [3, 5],
    "pointCount": 10,
    "yTick": {
      "text": "",
      "num": 4,
      "major": 10,
      "minor": 5,
      "axis": "CHART_AXIS_INVERSE_LABELS_ORDER"
    },
    "xTick": {
      "text": "",
      "num": 4,
      "major": 10,
      "minor": 5,
      "axis": "CHART_AXIS_DRAW_LAST_TICK"
    },
    "defaultStatus": {
      "bgPart": {
        "border": {
          "color": "#E6E6E6",
          "width": 1
        },
        "bg": {
          "color": "#FFFFFF",
          "opa": 255
        },
        "pad": {
          "top": 5,
          "bottom": 5,
          "left": 5,
          "right": 5
        }
      },
      "seriesBgPart": {},
      "seriesPart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景"
    },
    {
      "value": "SERIES",
      "text": "数据"
    },
    {
      "value": "SERIES_BG",
      "text": "数据背景"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    },
    {
      "title": "线属性",
      "name": "partStyle.line",
      "type": "Object",
      "comType": "LvglMakerStyleLine"
    },
    {
      "title": "文字样式",
      "name": "partStyle.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    },
    {
      "title": "边框",
      "name": "partStyle.border",
      "type": "Object",
      "comType": "LvglMakerStyleBorder"
    }
  ],
  "seriesPartFields": [
    {
      "title": "半径",
      "name": "partStyle.radius",
      "type": "Integer",
      "comType": "TiInputNum"
    },
    {
      "title": "间隔",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    }
  ],
  "seriesBgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "线属性",
      "name": "partStyle.line",
      "type": "Object",
      "comType": "LvglMakerStyleLine"
    },
    {
      "title": "轴间距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    }
  ],
  "propFields": [
    {
      "title": "外观类型",
      "name": "type",
      "defaultAs": "CHART_TYPE_LINE",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "value": "CHART_TYPE_NONE",
            "text": "隐藏"
          },
          {
            "value": "CHART_TYPE_LINE",
            "text": "折线图"
          },
          {
            "value": "CHART_TYPE_COLUMN",
            "text": "柱状图"
          }
        ]
      }
    },
    {
      "title": "显示点数",
      "tip": "X轴显示的点位数量",
      "name": "pointCount",
      "defaultAs": 10,
      "width": 120,
      "type": "Integer",
      "comType": "TiInputNum",
      "comConf": {
        "step": 1,
        "minValue": 2,
        "maxValue": 10000
      }
    },
    {
      "title": "分割线",
      "name": "divLineCount",
      "tip": "水平分割+垂直分割，中间用半角逗号分隔",
      "type": "Array",
      "width": 120,
      "serializer": "Minke.rangeToArray",
      "comConf": {
        "placeholder": "3,5"
      }
    },
    {
      "title": "数据设置"
    },
    {
      "name": "series",
      "type": "Array",
      "comType": "TiComboTable",
      "comConf": {
        "newItemText": "添加数据",
        "blankAs": {
          "text": "并未设置任何数据"
        },
        "list": {
          "fields": [
            {
              "title": "颜色",
              "display": {
                "key": "color",
                "comConf": {
                  "className": "flex-auto",
                  "style": {
                    "color": "#F0F0F0",
                    "background-color": ":=item.color"
                  }
                }
              }
            },
            {
              "title": "数据列表",
              "display": {
                "key": "points",
                "comConf": {
                  "className": "flex-auto"
                }
              }
            },
            {
              "title": "起始下标",
              "display": {
                "key": "start",
                "comConf": {
                  "className": "flex-auto"
                }
              }
            }
          ]
        },
        "dialog": {
          "title": "编辑数据",
          "width": "4.8rem",
          "height": "5.2rem"
        },
        "form": {
          "fields": [
            {
              "title": "颜色",
              "name": "color",
              "comType": "TiInputColor"
            },
            {
              "title": "数据列表",
              "name": "points",
              "type": "Array",
              "serializer": "Minke.rangeToArray",
              "comType": "TiInput",
              "comConf": {
                "placeholder": "1,10,20,30"
              }
            },
            {
              "title": "起始下标",
              "name": "start",
              "type": "Integer",
              "comType": "TiInputNum",
              "comConf": {
                "placeholder": "默认从0开始",
                "step": 1,
                "minValue": 0,
                "maxValue": 10000
              }
            }
          ]
        }
      }
    },
    {
      "title": "刷新时长",
      "name": "wait",
      "type": "Integer",
      "default": 0,
      "comType": "TiInput",
      "comConf": {
        "suffixText": "毫秒"
      }
    },
    {
      "title": "更新模式",
      "name": "updateMode",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "value": "CHART_UPDATE_MODE_SHIFT",
            "text": "尾部添加"
          },
          {
            "value": "CHART_UPDATE_MODE_CIRCULAR",
            "text": "循环添加"
          }
        ]
      }
    },
    {
      "title": "Y轴设置"
    },
    {
      "title": "Y值区间",
      "name": "yRange",
      "tip": "最小值和最大值，中间用半角逗号分隔",
      "width": 120,
      "type": "Array",
      "serializer": "Minke.rangeToArray",
      "comConf": {
        "placeholder": "0,100"
      }
    },
    {
      "title": "Y轴样式",
      "name": "yTick.axis",
      "comType": "TiDroplist",
      "comConf": {
        "options": [
          {
            "value": "CHART_AXIS_DRAW_LAST_TICK",
            "text": "绘制最后刻度"
          },
          {
            "value": "CHART_AXIS_SKIP_LAST_TICK",
            "text": "不绘制最后刻度"
          },
          {
            "value": "CHART_AXIS_INVERSE_LABELS_ORDER",
            "text": "倒序绘制标签"
          }
        ]
      }
    },
    {
      "title": "Y轴刻度文本",
      "name": "yTick.text",
      "comType": "TiInputText",
      "tip": "一行一个文本内容"
    },
    {
      "title": "Y轴刻度间隔",
      "name": "yTick.num",
      "type": "Integer",
      "defaultAs": 1,
      "tip": "两个标签之间的刻度数"
    },
    {
      "title": "Y轴主刻度长度",
      "name": "yTick.major",
      "defaultAs": 10,
      "type": "Integer"
    },
    {
      "title": "Y轴小刻度长度",
      "name": "yTick.minor",
      "defaultAs": 5,
      "type": "Integer"
    },
    {
      "title": "X轴设置"
    },
    {
      "title": "X轴样式",
      "name": "xTick.axis",
      "comType": "TiDroplist",
      "comConf": {
        "options": [
          {
            "value": "CHART_AXIS_DRAW_LAST_TICK",
            "text": "绘制最后刻度"
          },
          {
            "value": "CHART_AXIS_SKIP_LAST_TICK",
            "text": "不绘制最后刻度"
          }
        ]
      }
    },
    {
      "title": "X轴刻度文本",
      "name": "xTick.text",
      "comType": "TiInputText",
      "tip": "一行一个文本内容"
    },
    {
      "title": "X轴刻度间隔",
      "name": "xTick.num",
      "type": "Integer",
      "defaultAs": 1,
      "tip": "两个标签之间的刻度数"
    },
    {
      "title": "X轴主刻度长度",
      "name": "xTick.major",
      "defaultAs": 10,
      "type": "Integer"
    },
    {
      "title": "X轴小刻度长度",
      "name": "xTick.minor",
      "defaultAs": 5,
      "type": "Integer"
    }
  ],
  "comEvents": ["#GENERIC_EVENTS", "VALUE_CHANGED"]
});
//========================================
// JOIN <lvgl-chart.html> com/lvgl/core/chart/lvgl-chart.html
//========================================
Ti.Preload("com/lvgl/core/chart/lvgl-chart.html", `<div class="lvgl-com-chart" :style="containerBgStyle">
  <svg class="chart-svg" :width="xSize" :height="ySize" :viewPort="viewPort" version="1.1"
    xmlns="http://www.w3.org/2000/svg" :style="svgStyle">
    <!-- 背景分割线 -->
    <line v-for="(hline,idx) in divisionLines.h" :key="'divh_' + idx" :x1="hline.x1" :x2="hline.x2" :y1="hline.y1"
      :y2="hline.y2" :style="hline.style"></line>
    <line v-for="(vline,idx) in divisionLines.v" :key="'divv_' + idx" :x1="vline.x1" :x2="vline.x2" :y1="vline.y1"
      :y2="vline.y2" :style="vline.style"></line>

    <!-- y轴 刻度 -->
    <text v-for="(t,idx) in yTicks.texts" :key="'ytick_t_' + idx" :font-size="t.fontSize" :x="t.x" :y="t.y"
      :textLength="t.content.length * 2" lengthAdjust="spacing" :style="t.style">{{t.content}}</text>
    <line v-for="(mark,idx) in yTicks.marks" :key="'ytick_mark_' + idx" :x1="mark.x1" :x2="mark.x2" :y1="mark.y1"
      :y2="mark.y2" :style="mark.style"></line>

    <!-- x轴 刻度 -->
    <text v-for="(t,idx) in xTicks.texts" :key="'xtick_t_' + idx" :font-size="t.fontSize" :x="t.x" :y="t.y"
      :textLength="t.content.length * 2" lengthAdjust="spacing" :style="t.style">{{t.content}}</text>
    <line v-for="(mark,idx) in xTicks.marks" :key="'xtick_mark_' + idx" :x1="mark.x1" :x2="mark.x2" :y1="mark.y1"
      :y2="mark.y2" :style="mark.style"></line>

    <!-- 数据 折线图 -->
    <polyline v-for="(dl,idx) in seriesDataLine.dlines" :key="'datal_' + idx" :points="dl.points" :style="dl.style">
    </polyline>
    <circle v-for="(dc,idx) in seriesDataLine.dcircles" :key="'dataC_' + idx" :r="dc.r" :cx="dc.x" :cy="dc.y"
      :style="dc.style">
    </circle>

    <!-- 数据 柱状图 -->
    <rect v-for="(dcol,idx) in seriesDataColumn.dcolumns" :key="'dataCol_' + idx" :x="dcol.x" :y="dcol.y"
      :width="dcol.width" :height="dcol.height" :style="dcol.style"></rect>
  </svg>
</div>`);
//========================================
// JOIN <lvgl-chart.mjs> com/lvgl/core/chart/lvgl-chart.mjs
//========================================
Ti.Preload("com/lvgl/core/chart/lvgl-chart.mjs", TI_PACK_EXPORTS['com/lvgl/core/chart/lvgl-chart.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/chart/_com.json
//========================================
Ti.Preload("com/lvgl/core/chart/_com.json", {
  "name": "LvglChart",
  "globally": true,
  "template": "./lvgl-chart.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-chart.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/cont/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/cont/hmaker.json", {
  "icon": "zmdi-view-quilt",
  "title": "布局容器",
  "measure": {
    "width": 225,
    "height": 150
  },
  "defaultPart": "MAIN",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "layout": "LAYOUT_OFF",
    "fit": "FIT_NONE"
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "MAIN",
      "text": "主区域"
    }
  ],
  "mainPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    },
    {
      "title": "边框",
      "name": "partStyle.border",
      "type": "Object",
      "comType": "LvglMakerStyleBorder"
    }
  ],
  "propFields": [
    {
      "title": "布局",
      "name": "layout",
      "defaultAs": "LAYOUT_OFF",
      "comType": "TiDroplist",
      "comConf": {
        "placeholder": "LAYOUT_OFF",
        "options": [
          "LAYOUT_OFF",
          "LAYOUT_CENTER",
          "LAYOUT_COLUMN_LEFT",
          "LAYOUT_COLUMN_MID",
          "LAYOUT_COLUMN_RIGHT",
          "LAYOUT_ROW_TOP",
          "LAYOUT_ROW_MID",
          "LAYOUT_ROW_BOTTOM",
          "LAYOUT_PRETTY_TOP",
          "LAYOUT_PRETTY_MID",
          "LAYOUT_PRETTY_BOTTOM",
          "LAYOUT_GRID"
        ],
        "dropDisplay": "text"
      }
    },
    {
      "title": "自动填充",
      "name": "fit",
      "defaultAs": "FIT_NONE",
      "comType": "TiDroplist",
      "comConf": {
        "placeholder": "FIT_NONE",
        "options": [
          "FIT_NONE",
          "FIT_TIGHT",
          "FIT_PARENT",
          "FIT_MAX"
        ],
        "dropDisplay": "text"
      }
    }
  ],
  "comEvents": [
    "#GENERIC_EVENTS"
  ]
});
//========================================
// JOIN <lvgl-cont.html> com/lvgl/core/cont/lvgl-cont.html
//========================================
Ti.Preload("com/lvgl/core/cont/lvgl-cont.html", `<div class="lvgl-com-cont" :style="PartMainStyle"></div>
<div class="lvgl-com-cont" :style="PartMainStyle"></div>`);
//========================================
// JOIN <lvgl-cont.mjs> com/lvgl/core/cont/lvgl-cont.mjs
//========================================
Ti.Preload("com/lvgl/core/cont/lvgl-cont.mjs", TI_PACK_EXPORTS['com/lvgl/core/cont/lvgl-cont.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/cont/_com.json
//========================================
Ti.Preload("com/lvgl/core/cont/_com.json", {
  "name": "LvglCont",
  "globally": true,
  "template": "./lvgl-cont.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-cont.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/cpicker/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/cpicker/hmaker.json", {
  "icon": "fas-palette",
  "title": "颜色拾取器",
  "measure": {
    "width": 250,
    "height": 250
  },
  "defaultPart": "BG",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "defaultStatus": {
      "bgPart": {},
      "indicPart": {},
      "knobPart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景弧"
    },
    {
      "value": "KNOB",
      "text": "控制柄"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "渐变半径",
      "name": "partStyle.radius",
      "type": "Integer",
      "comType": "TiInputNum"
    },
    {
      "title": "线属性",
      "name": "partStyle.line",
      "type": "Object",
      "comType": "LvglMakerStyleLine"
    }
  ],
  "indicPartFields": [
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    },
    {
      "title": "线属性",
      "name": "partStyle.line",
      "type": "Object",
      "comType": "LvglMakerStyleLine"
    }
  ],
  "knobPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "渐变半径",
      "name": "partStyle.radius",
      "type": "Integer",
      "comType": "TiInputNum"
    },
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    }
  ],
  "propFields": [
    {
      "title": "外观类型",
      "name": "type",
      "defaultAs": "NORMAL",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "value": "NORMAL",
            "text": "正向弧"
          },
          {
            "value": "REVERSE",
            "text": "反向弧"
          },
          {
            "value": "SYMMETRIC",
            "text": "对称弧"
          }
        ]
      }
    },
    {
      "title": "数据"
    },
    {
      "title": "值区间",
      "name": "range",
      "tip": "最小值和最大值，中间用半角逗号分隔",
      "type": "Array",
      "comConf": {
        "placeholder": "0, 100"
      }
    },
    {
      "title": "当前值",
      "name": "value",
      "tip": "输入一个最小值和最大值之间的整数",
      "type": "Integer"
    },
    {
      "title": "整体旋转",
      "name": "rotationAngle",
      "tip": "角度值: 0-360",
      "type": "Integer"
    },
    {
      "title": "背景弧"
    },
    {
      "title": "开始角度",
      "name": "bgStartAngle",
      "tip": "角度值: 0-360",
      "type": "Integer"
    },
    {
      "title": "结束角度",
      "name": "bgEndAngle",
      "tip": "角度值: 0-360",
      "type": "Integer"
    },
    {
      "title": "前景弧"
    },
    {
      "title": "开始角度",
      "name": "arcStartAngle",
      "tip": "角度值: 0-360",
      "type": "Integer"
    },
    {
      "title": "结束角度",
      "name": "arcEndAngle",
      "tip": "角度值: 0-360",
      "type": "Integer"
    }
  ],
  "comEvents": [
    "#GENERIC_EVENTS",
    "VALUE_CHANGED"
  ]
});
//========================================
// JOIN <lvgl-cpicker.html> com/lvgl/core/cpicker/lvgl-cpicker.html
//========================================
Ti.Preload("com/lvgl/core/cpicker/lvgl-cpicker.html", `<div class="lvgl-com-cpicker" :class="TopClass"> 
  
</div>`);
//========================================
// JOIN <lvgl-cpicker.mjs> com/lvgl/core/cpicker/lvgl-cpicker.mjs
//========================================
Ti.Preload("com/lvgl/core/cpicker/lvgl-cpicker.mjs", TI_PACK_EXPORTS['com/lvgl/core/cpicker/lvgl-cpicker.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/cpicker/_com.json
//========================================
Ti.Preload("com/lvgl/core/cpicker/_com.json", {
  "name": "LvglCPicker",
  "globally": true,
  "template": "./lvgl-cpicker.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-cpicker.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/dropdown/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/dropdown/hmaker.json", {
  "icon": "fas-caret-square-down",
  "title": "下拉菜单",
  "measure": {
    "width": 100,
    "height": 30
  },
  "defaultPart": "MAIN",
  "defaultStatus": "DEFAULT",
  "defaultResizable": "ew-resize",
  "comConf": {
    "selected": 0,
    "options": "选项1\n选项2\n选项3",
    "defaultStatus": {
      "mainPart": {
        "text": {
          "font": {
            "name": "SimSun",
            "size": 16,
            "weight": "NORMAL"
          }
        }
      },
      "listPart": {},
      "scrollbarPart": {},
      "selectedPart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "MAIN",
      "text": "主体"
    },
    {
      "value": "LIST",
      "text": "下拉列表"
    },
    {
      "value": "SCROLLBAR",
      "text": "滚动条"
    },
    {
      "value": "SELECTED",
      "text": "选中内容"
    }
  ],
  "mainPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "边框",
      "name": "partStyle.border",
      "type": "Object",
      "comType": "LvglMakerStyleBorder"
    },
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    },
    {
      "title": "文字样式",
      "name": "partStyle.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    }
  ],
  "listPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "文字样式",
      "name": "partStyle.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    }
  ],
  "scrollbarPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "selectedPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "propFields": [
    {
      "title": "候选内容",
      "name": "options",
      "tip": "候选值一行一个",
      "fieldWith": "100%",
      "comType": "TiInputText"
    },
    {
      "title": "选中下标",
      "name": "selected",
      "tip": "下标起始从0开始",
      "type": "Number"
    },
    {
      "title": "列表方位",
      "name": "dir",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "value": "DROPDOWN_DIR_LEFT",
            "text": "左"
          },
          {
            "value": "DROPDOWN_DIR_RIGHT",
            "text": "右"
          },
          {
            "value": "DROPDOWN_DIR_UP",
            "text": "上"
          },
          {
            "value": "DROPDOWN_DIR_DOWN",
            "text": "下"
          }
        ]
      }
    },
    {
      "title": "列表最大高度",
      "name": "maxHeight",
      "type": "Number",
      "tip": "默认为3/4屏幕垂直高度"
    },
    {
      "title": "动画时长",
      "name": "animTime",
      "type": "Integer",
      "width": 120,
      "comType": "TiInput",
      "comConf": {
        "suffixText": "ms"
      }
    }
  ],
  "comEvents": [
    "KEY_UP",
    "KEY_RIGHT",
    "KEY_DOWN",
    "KEY_LEFT",
    "KEY_ENTER",
    "VALUE_CHANGED"
  ]
});
//========================================
// JOIN <lvgl-dropdown.html> com/lvgl/core/dropdown/lvgl-dropdown.html
//========================================
Ti.Preload("com/lvgl/core/dropdown/lvgl-dropdown.html", `<div class="lvgl-com-dropdown">
  <!--下拉菜单 -->
  <div class="dd-list" :style="partMainStyle">
    <div class="dd-list-option">{{optionSelected}}</div>
    <div class="dd-list-icon"><i class="fas fa-chevron-down"></i></div>
  </div>
</div>`);
//========================================
// JOIN <lvgl-dropdown.mjs> com/lvgl/core/dropdown/lvgl-dropdown.mjs
//========================================
Ti.Preload("com/lvgl/core/dropdown/lvgl-dropdown.mjs", TI_PACK_EXPORTS['com/lvgl/core/dropdown/lvgl-dropdown.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/dropdown/_com.json
//========================================
Ti.Preload("com/lvgl/core/dropdown/_com.json", {
  "name": "LvglDropdown",
  "globally": true,
  "template": "./lvgl-dropdown.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-dropdown.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/gauge/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/gauge/hmaker.json", {
  "icon": "fas-tachometer-alt",
  "title": "仪表盘",
  "forceRatio": true,
  "measure": {
    "width": 100,
    "height": 100
  },
  "defaultPart": "MAIN",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "needles": [
      {
        "value": 10,
        "color": "#FF0000"
      }
    ],
    "scale": [220, 21, 6],
    "range": [0, 100],
    "criticalValue": 80,
    "angleOffset": 0,
    "defaultStatus": {
      "mainPart": {},
      "majorPart": {},
      "needlePart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "MAIN",
      "text": "背景"
    },
    {
      "value": "MAJOR",
      "text": "表盘"
    },
    {
      "value": "NEEDLE",
      "text": "指针"
    }
  ],
  "mainPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "majorPartFields": [
    {
      "title": "线属性",
      "name": "partStyle.line",
      "type": "Object",
      "comType": "LvglMakerStyleLine"
    }
  ],
  "needlePartFields": [
    {
      "title": "线属性",
      "name": "partStyle.line",
      "type": "Object",
      "comType": "LvglMakerStyleLine"
    }
  ],
  "propFields": [
    {
      "title": "指针设置"
    },
    {
      "name": "needles",
      "type": "Array",
      "comType": "TiComboTable",
      "comConf": {
        "newItemText": "添加指针",
        "blankAs": {
          "text": "并未设置任何指针"
        },
        "list": {
          "fields": [
            {
              "title": "指针颜色",
              "display": {
                "key": "color",
                "comConf": {
                  "className": "flex-auto",
                  "style": {
                    "color": "#F0F0F0",
                    "background-color": ":=item.color"
                  }
                }
              }
            },
            {
              "title": "指针值",
              "display": "value"
            }
          ]
        },
        "dialog": {
          "title": "编辑指针",
          "width": "4.8rem",
          "height": "5.2rem"
        },
        "form": {
          "fields": [
            {
              "title": "指针颜色",
              "name": "color",
              "comType": "TiInputColor"
            },
            {
              "title": "指针值",
              "name": "value",
              "type": "Integer",
              "comType": "TiInputNum",
              "comConf": {
                "placeholder": "0",
                "minValue": "=item.range.0",
                "maxValue": "=item.range.1",
                "step": 10
              }
            }
          ]
        }
      }
    },
    {
      "title": "其他参数"
    },
    {
      "title": "表盘参数",
      "name": "scale",
      "tip": "角度最大值，线数数量，标签数",
      "type": "Array",
      "serializer": "Minke.rangeToArray",
      "width": 120,
      "comConf": {
        "placeholder": "220,21,6"
      }
    },
    {
      "title": "值区间",
      "name": "range",
      "tip": "最小值和最大值，中间用半角逗号分隔",
      "type": "Array",
      "width": 120,
      "serializer": "Minke.rangeToArray",
      "comConf": {
        "placeholder": "0,100"
      }
    },
    {
      "title": "临界值",
      "name": "criticalValue",
      "tip": "输入一个最小值和最大值之间的整数",
      "type": "Integer",
      "comConf": {
        "range": "=item.range"
      }
    },
    {
      "title": "整体旋转",
      "name": "angleOffset",
      "tip": "角度值: 0-360",
      "type": "Integer",
      "defaultAs": 0
    }
  ],
  "comEvents": ["#GENERIC_EVENTS"]
});
//========================================
// JOIN <lvgl-gauge.html> com/lvgl/core/gauge/lvgl-gauge.html
//========================================
Ti.Preload("com/lvgl/core/gauge/lvgl-gauge.html", `<div class="lvgl-com-gauge" :style="guageBgStyle">
  <svg class="gauge-svg" width="100" height="100" viewPort="0 0 100 100" version="1.1"
    xmlns="http://www.w3.org/2000/svg" :style="bgStyle">

    <!-- 表盘 -->
    <!-- 表盘 mark -->
    <line x1="90" y1="50" x2="96" y2="50" :style="mm" v-for="(mm, idx) in meterMarks" :key="'mark_' + idx" />
    <!-- 表盘 label-mark -->
    <line x1="86" y1="50" x2="96" y2="50" :style="lm" v-for="(lm, idx) in meterLabelMarks" :key="'label-mark_' + idx" />
    <!-- 表盘 label -->
    <text x="72" y="52.5" :style="label.style" v-for="(label, idx) in meterLabels"
      :key="'label_' + idx">{{label.text}}</text>
    <!-- 临街值 -->
    <circle :r="criR" :cx="criX" :cy="criY" fill="transparent" :style="meterCritical">
    </circle>

    <!-- 内容 -->
    <!-- 指针 -->
    <line x1="50" y1="50" x2="85" y2="50" :style="getNeedleStyle(idx, ndl)" v-for="(ndl, idx) in needles"
      :key="'needle_' +  idx" />
    <!-- 小球 -->
    <circle class="guage-center" :r="centerR" :cx="centerX" :cy="centerY" :style="centerStyle"></circle>

  </svg>
</div>`);
//========================================
// JOIN <lvgl-gauge.mjs> com/lvgl/core/gauge/lvgl-gauge.mjs
//========================================
Ti.Preload("com/lvgl/core/gauge/lvgl-gauge.mjs", TI_PACK_EXPORTS['com/lvgl/core/gauge/lvgl-gauge.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/gauge/_com.json
//========================================
Ti.Preload("com/lvgl/core/gauge/_com.json", {
  "name": "LvglGauge",
  "globally": true,
  "template": "./lvgl-gauge.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-gauge.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/img/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/img/hmaker.json", {
  "icon": "fas-image",
  "title": "图片",
  "forceRatio": true,
  "measure": {
    "width": 120,
    "height": 120
  },
  "defaultPart": "MAIN",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "defaultStatus": {
      "mainPart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "MAIN",
      "text": "主区域"
    }
  ],
  "mainPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "propFields": [
    {
      "title": "图片路径",
      "name": "src"
    }
  ],
  "comEvents": ["CLICKED"]
});
//========================================
// JOIN <lvgl-img.html> com/lvgl/core/img/lvgl-img.html
//========================================
Ti.Preload("com/lvgl/core/img/lvgl-img.html", `<div 
  :class="'lvgl-com-img ' + (myImgSrc ? '': 'not-set')" 
  @dblclick="OnDblClickImage">
  <img ref="img" :src="myImgSrc" :style="ImageStyle" @load="OnImageLoaded" />
</div>`);
//========================================
// JOIN <lvgl-img.mjs> com/lvgl/core/img/lvgl-img.mjs
//========================================
Ti.Preload("com/lvgl/core/img/lvgl-img.mjs", TI_PACK_EXPORTS['com/lvgl/core/img/lvgl-img.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/img/_com.json
//========================================
Ti.Preload("com/lvgl/core/img/_com.json", {
  "name": "LvglImg",
  "globally": true,
  "template": "./lvgl-img.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-img.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/imgbtn/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/imgbtn/hmaker.json", {
  "icon": "zmdi-gradient",
  "title": "图片按钮",
  "forceRatio": true,
  "defaultPart": "MAIN",
  "defaultStatus": "DEFAULT",
  "measure": {
    "width": 120,
    "height": 120
  },
  "comConf": {
    "state": "BTN_STATE_RELEASED",
    "defaultStatus": {
      "mainPart": {}
    }
  },
  "comTransition": true,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    },
    {
      "value": "PRESSED",
      "text": "按下"
    },
    {
      "value": "DISABLED",
      "text": "禁止"
    }
  ],
  "comParts": [
    {
      "value": "MAIN",
      "text": "主区域"
    }
  ],
  "mainPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "propFields": [
    {
      "title": "图片路径"
    },
    {
      "name": "src",
      "type": "Object",
      "comType": "TiObjPair",
      "comConf": {
        "nameText": "状态",
        "valueText": "路径",
        "canEditValue": true,
        "onlyFields": true,
        "emptyAsNull": true,
        "showEmpty": true,
        "fields": [
          {
            "title": "默认",
            "name": "released"
          },
          {
            "title": "按下",
            "name": "pressed"
          },
          {
            "title": "禁止",
            "name": "disabled"
          },
          {
            "title": "选中按下",
            "name": "checked_pressed"
          },
          {
            "title": "选中抬起",
            "name": "checked_released"
          }
        ]
      }
    },
    {
      "title": "自动切换状态",
      "width": "1.4rem",
      "name": "checkable",
      "type": "Boolean",
      "comType": "TiToggle"
    }
  ],
  "comEvents": ["#GENERIC_EVENTS", "VALUE_CHANGED"]
});
//========================================
// JOIN <lvgl-imgbtn.html> com/lvgl/core/imgbtn/lvgl-imgbtn.html
//========================================
Ti.Preload("com/lvgl/core/imgbtn/lvgl-imgbtn.html", `<div
  class="lvgl-com-imgbtn"
  :class="TopClass"
  @dblclick.stop="OnDblClickImage">
  <!--显示图片-->
  <img ref="img"
    v-if="myImgSrc"
      :src="myImgSrc"
      :style="ImageStyle"
      @load="OnImageLoaded"/>
  <!--占位符-->
  <div v-else
    :style="ImageStyle"
    class="img-placeholder"></div>
  <!--图片预加载-->
  <div class="as-img-preload" ref="preloads">
    <img 
      v-for="it in myPreloadSrcList"
        :key="it.key"
        :src="it.imgSrc"
        :data-index="it.index"
        @load="OnImagePreloaded(it)"/>
  </div>
</div>`);
//========================================
// JOIN <lvgl-imgbtn.mjs> com/lvgl/core/imgbtn/lvgl-imgbtn.mjs
//========================================
Ti.Preload("com/lvgl/core/imgbtn/lvgl-imgbtn.mjs", TI_PACK_EXPORTS['com/lvgl/core/imgbtn/lvgl-imgbtn.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/imgbtn/_com.json
//========================================
Ti.Preload("com/lvgl/core/imgbtn/_com.json", {
  "name": "LvglImgBtn",
  "globally": true,
  "template": "./lvgl-imgbtn.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-imgbtn.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/keyboard/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/keyboard/hmaker.json", {
  "icon": "fas-keyboard",
  "title": "虚拟键盘",
  "measure": {
    "width": 200,
    "height": 85
  },
  "defaultPart": "BG",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "hiddenKeyboard": true,
    "defaultStatus": {
      "bgPart": {},
      "btnPart": {
        "text": {
          "font": {
            "name": "SimSun",
            "size": 16,
            "weight": "NORMAL"
          }
        }
      }
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景"
    },
    {
      "value": "BTN",
      "text": "按键"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "btnPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "文字样式",
      "name": "partStyle.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    }
  ],
  "propFields": [
    {
      "title": "关联文本框",
      "name": "textarea",
      "nameVAlign": "top",
      "tip": "请输入文本框的ID名称",
      "comType": "TiInput"
    },
    {
      "title": "文本框隐藏键盘",
      "name": "hiddenKeyboard",
      "type": "Boolean",
      "comType": "TiToggle"
    },
    {
      "title": "控制输入光标",
      "name": "cursorManage",
      "type": "Boolean",
      "comType": "TiToggle"
    },
    {
      "title": "按键类型",
      "name": "mode",
      "defaultAs": "KEYBOARD_MODE_TEXT_LOWER",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "value": "KEYBOARD_MODE_TEXT_LOWER",
            "text": "小写"
          },
          {
            "value": "KEYBOARD_MODE_TEXT_UPPER",
            "text": "大写"
          },
          {
            "value": "KEYBOARD_MODE_SPECIAL",
            "text": "特殊"
          },
          {
            "value": "KEYBOARD_MODE_NUM",
            "text": "数字"
          }
        ]
      }
    }
  ],
  "comEvents": [
    "#GENERIC_EVENTS",
    "VALUE_CHANGED",
    "APPLY",
    "CANCEL"
  ]
});
//========================================
// JOIN <lvgl-keyboard.html> com/lvgl/core/keyboard/lvgl-keyboard.html
//========================================
Ti.Preload("com/lvgl/core/keyboard/lvgl-keyboard.html", `<div class="lvgl-com-keyboard">
  <div class="keyboard-container" :style="BgStyle">
    <div class="keyboard-line" v-for="(line, no) in BtnMatrix" :key="'line-' + no" :style="BtnLineStyle">
      <div class="keyboard-btn" v-for="btn in line" :key="btn.text || btn.label" :style="getBtnItemStyle(btn)">
        <div v-if="btn.label" class="keyboard-btn-label" :style="getBtnLabelStyle(btn)">{{btn.label}}</div>
      </div>
    </div>
  </div>
</div>`);
//========================================
// JOIN <lvgl-keyboard.mjs> com/lvgl/core/keyboard/lvgl-keyboard.mjs
//========================================
Ti.Preload("com/lvgl/core/keyboard/lvgl-keyboard.mjs", TI_PACK_EXPORTS['com/lvgl/core/keyboard/lvgl-keyboard.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/keyboard/_com.json
//========================================
Ti.Preload("com/lvgl/core/keyboard/_com.json", {
  "name": "LvglKeyboard",
  "globally": true,
  "template": "./lvgl-keyboard.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-keyboard.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/label/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/label/hmaker.json", {
  "icon": "fas-tag",
  "title": "标签",
  "defaultPart": "MAIN",
  "defaultStatus": "DEFAULT",
  "defaultResizable": "auto",
  "measure": {},
  "comConf": {
    "text": "Label Text",
    "longMode": "LABEL_LONG_EXPAND",
    "align": "LABEL_ALIGN_LEFT",
    "defaultStatus": {
      "mainPart": {
        "text": {
          "font": {
            "name": "SimSun",
            "size": 16,
            "weight": "NORMAL"
          }
        }
      }
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "MAIN",
      "text": "主区域"
    }
  ],
  "mainPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "文字样式",
      "name": "partStyle.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    }
  ],
  "propFields": [
    {
      "title": "文字内容",
      "name": "text",
      "comType": "TiInputText"
    },
    {
      "title": "长文本",
      "name": "longMode",
      "comType": "TiDroplist",
      "comConf": {
        "options": [
          {
            "value": "LABEL_LONG_EXPAND",
            "text": "扩展对象尺寸"
          },
          {
            "value": "LABEL_LONG_BREAK",
            "text": "保持对象宽度，并将文字折行"
          },
          {
            "value": "LABEL_LONG_DOT",
            "text": "截断文字，并在结尾输出省略号"
          },
          {
            "value": "LABEL_LONG_SROLL",
            "text": "显示滚动条"
          },
          {
            "value": "LABEL_LONG_SROLL_CIRC",
            "text": "循环滚动"
          },
          {
            "value": "LABEL_LONG_CROP",
            "text": "直接剪裁文本"
          }
        ]
      }
    },
    {
      "title": "文本排列",
      "name": "align",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "icon": "fas-align-left",
            "value": "LABEL_ALIGN_LEFT",
            "tip": "居左"
          },
          {
            "icon": "fas-align-center",
            "value": "LABEL_ALIGN_CENTER",
            "tip": "居中"
          },
          {
            "icon": "fas-align-right",
            "value": "LABEL_ALIGN_RIGHT",
            "tip": "居右"
          }
        ]
      }
    },
    {
      "title": "指定颜色",
      "name": "recolor",
      "type": "Boolean",
      "comType": "TiToggle"
    },
    {
      "title": "滚动速度",
      "name": "animSpeed",
      "type": "Integer",
      "width": 120,
      "comType": "TiInput",
      "comConf": {
        "suffixText": "像素/秒"
      }
    }
  ],
  "comEvents": ["#GENERIC_EVENTS"]
});
//========================================
// JOIN <lvgl-label.html> com/lvgl/core/label/lvgl-label.html
//========================================
Ti.Preload("com/lvgl/core/label/lvgl-label.html", `<div class="lvgl-com-label" :class="TopClass" :style="TopStyle">
  <div class="part-main" :style="PartMainStyle">
    <div class="part-text" :style="PartTextStyle">
      <p v-html="ValueHtml"></p>
    </div>
  </div>
</div>`);
//========================================
// JOIN <lvgl-label.mjs> com/lvgl/core/label/lvgl-label.mjs
//========================================
Ti.Preload("com/lvgl/core/label/lvgl-label.mjs", TI_PACK_EXPORTS['com/lvgl/core/label/lvgl-label.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/label/_com.json
//========================================
Ti.Preload("com/lvgl/core/label/_com.json", {
  "name": "LvglLabel",
  "globally": true,
  "template": "./lvgl-label.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-label.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/led/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/led/hmaker.json", {
  "icon": "far-lightbulb",
  "title": "LED",
  "defaultPart": "MAIN",
  "defaultStatus": "DEFAULT",
  "measure": {
    "width": 100,
    "height": 100
  },
  "comConf": {
    "bright": 200,
    "state": "ON",
    "toggle": false,
    "defaultStatus": {
      "mainPart": {
        "bg": {
          "color": "#00FF00"
        }
      }
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "MAIN",
      "text": "主区域"
    }
  ],
  "mainPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "propFields": [
    {
      "title": "亮度",
      "name": "bright",
      "tip": "0 - 255 的整数值。越小越暗",
      "type": "Integer",
      "defaultAs": 255,
      "comType": "TiInputNum",
      "comConf": {
        "step": 10,
        "minValue": 0,
        "maxValue": 255
      }
    },
    {
      "title": "亮灯状态",
      "name": "state",
      "comType": "TiSwitcher",
      "comConf": {
        "options": ["ON", "OFF"]
      }
    },
    {
      "title": "点击切换",
      "name": "toggle",
      "type": "Boolean",
      "comType": "TiToggle"
    }
  ],
  "comEvents": ["#GENERIC_EVENTS"]
});
//========================================
// JOIN <lvgl-led.html> com/lvgl/core/led/lvgl-led.html
//========================================
Ti.Preload("com/lvgl/core/led/lvgl-led.html", `<div class="lvgl-com-led" :class="TopClass"> 
  <div class="part-main" :style="PartMainStyle"></div>
</div>`);
//========================================
// JOIN <lvgl-led.mjs> com/lvgl/core/led/lvgl-led.mjs
//========================================
Ti.Preload("com/lvgl/core/led/lvgl-led.mjs", TI_PACK_EXPORTS['com/lvgl/core/led/lvgl-led.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/led/_com.json
//========================================
Ti.Preload("com/lvgl/core/led/_com.json", {
  "name": "LvglLed",
  "globally": true,
  "template": "./lvgl-led.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-led.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/page/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/page/hmaker.json", {
  "icon": "fas-scroll",
  "title": "页面容器",
  "measure": {
    "width": 225,
    "height": 150
  },
  "defaultPart": "MAIN",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "layout": "LAYOUT_OFF",
    "fit": "FIT_NONE"
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景"
    },
    {
      "value": "SCRL",
      "text": "滚动条"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    },
    {
      "title": "边框",
      "name": "partStyle.border",
      "type": "Object",
      "comType": "LvglMakerStyleBorder"
    }
  ],
  "scrlPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    },
    {
      "title": "尺寸",
      "name": "partStyle.size",
      "type": "Integer",
      "defaultAs": 8,
      "comType": "TiInputNum"
    }
  ],
  "propFields": [
    {
      "title": "布局",
      "name": "layout",
      "defaultAs": "LAYOUT_OFF",
      "comType": "TiDroplist",
      "comConf": {
        "placeholder": "LAYOUT_OFF",
        "options": [
          "LAYOUT_OFF",
          "LAYOUT_CENTER",
          "LAYOUT_COLUMN_LEFT",
          "LAYOUT_COLUMN_MID",
          "LAYOUT_COLUMN_RIGHT",
          "LAYOUT_ROW_TOP",
          "LAYOUT_ROW_MID",
          "LAYOUT_ROW_BOTTOM",
          "LAYOUT_PRETTY_TOP",
          "LAYOUT_PRETTY_MID",
          "LAYOUT_PRETTY_BOTTOM",
          "LAYOUT_GRID"
        ],
        "dropDisplay": "text"
      }
    },
    {
      "title": "自动填充",
      "name": "fit",
      "defaultAs": "FIT_NONE",
      "comType": "TiDroplist",
      "comConf": {
        "placeholder": "FIT_NONE",
        "options": [
          "FIT_NONE",
          "FIT_TIGHT",
          "FIT_PARENT",
          "FIT_MAX"
        ],
        "dropDisplay": "text"
      }
    },
    {
      "title": "滚动模式",
      "name": "scrlbarMode",
      "defaultAs": "SCRLBAR_MODE_AUTO",
      "comType": "TiDroplist",
      "comConf": {
        "placeholder": "SCRLBAR_MODE_AUTO",
        "options": [
          "SCRLBAR_MODE_OFF",
          "SCRLBAR_MODE_ON",
          "SCRLBAR_MODE_DRAG",
          "SCRLBAR_MODE_AUTO",
          "SCRLBAR_MODE_HIDE",
          "SCRLBAR_MODE_UNHIDE"
        ],
        "dropDisplay": "text"
      }
    },
    {
      "title": "动画时长",
      "name": "animTime",
      "type": "Integer",
      "comType": "TiInput",
      "comConf": {
        "placeholder": "0",
        "suffixText": "毫秒"
      }
    },
    {
      "title": "边缘闪烁",
      "name": "edgeFlash",
      "type": "Boolean",
      "comType": "TiToggle"
    },
    {
      "title": "滚动传播",
      "name": "scrollPropagation",
      "type": "Boolean",
      "comType": "TiToggle"
    }
  ],
  "comEvents": [
    "#GENERIC_EVENTS"
  ]
});
//========================================
// JOIN <lvgl-page.html> com/lvgl/core/page/lvgl-page.html
//========================================
Ti.Preload("com/lvgl/core/page/lvgl-page.html", `<div class="lvgl-com-cont" :style="PartMainStyle"></div>
<div class="lvgl-com-cont" :style="PartMainStyle"></div>`);
//========================================
// JOIN <lvgl-page.mjs> com/lvgl/core/page/lvgl-page.mjs
//========================================
Ti.Preload("com/lvgl/core/page/lvgl-page.mjs", TI_PACK_EXPORTS['com/lvgl/core/page/lvgl-page.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/page/_com.json
//========================================
Ti.Preload("com/lvgl/core/page/_com.json", {
  "name": "LvglPage",
  "globally": true,
  "template": "./lvgl-page.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-page.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/qrcode/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/qrcode/hmaker.json", {
  "icon": "fa-qrcode",
  "title": "二维码",
  "forceRatio": true,
  "measure": {
    "width": 120,
    "height": 120
  },
  "defaultPart": "MAIN",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "txt": "",
    "defaultStatus": {
      "mainPart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "MAIN",
      "text": "主区域"
    }
  ],
  "mainPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "propFields": [
    {
      "title": "文本内容",
      "fieldWith": "100%",
      "tip": "请填写二维码内容",
      "name": "txt"
    }
  ],
  "comEvents": ["CLICKED"]
});
//========================================
// JOIN <lvgl-qrcode.html> com/lvgl/core/qrcode/lvgl-qrcode.html
//========================================
Ti.Preload("com/lvgl/core/qrcode/lvgl-qrcode.html", `<div class="lvgl-com-qrcode">
  <div ref="qrcode" class="qrcode" :style="ImageStyle"></div>
</div>`);
//========================================
// JOIN <lvgl-qrcode.mjs> com/lvgl/core/qrcode/lvgl-qrcode.mjs
//========================================
Ti.Preload("com/lvgl/core/qrcode/lvgl-qrcode.mjs", TI_PACK_EXPORTS['com/lvgl/core/qrcode/lvgl-qrcode.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/qrcode/_com.json
//========================================
Ti.Preload("com/lvgl/core/qrcode/_com.json", {
  "name": "LvglQrcode",
  "globally": true,
  "template": "./lvgl-qrcode.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-qrcode.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/slider/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/slider/hmaker.json", {
  "icon": "fas-sliders-h",
  "title": "滑块",
  "measure": {
    "width": 200,
    "height": 20
  },
  "defaultPart": "BG",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "value": [50, "ANIM_OFF"],
    "range": [0, 100],
    "advHittest": false,
    "defaultStatus": {
      "bgPart": {},
      "indicPart": {},
      "knobPart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景"
    },
    {
      "value": "INDIC",
      "text": "指示器"
    },
    {
      "value": "KNOB",
      "text": "控制柄"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    }
  ],
  "indicPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "knobPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    }
  ],
  "propFields": [
    {
      "title": "数据"
    },
    {
      "title": "当前值",
      "name": "value",
      "tip": "输入一个最小值和最大值之间的整数",
      "type": "Array",
      "comType": "LvglMakerFormAnimatVal",
      "comConf": {
        "range": "=item.range"
      }
    },
    {
      "title": "值区间",
      "name": "range",
      "tip": "最小值和最大值，中间用半角逗号分隔",
      "type": "Array",
      "width": 120,
      "serializer": "Minke.rangeToArray",
      "comConf": {
        "placeholder": "0,100"
      }
    },
    {
      "title": "其他"
    },
    {
      "title": "外观类型",
      "name": "type",
      "defaultAs": "SLIDER_TYPE_NORMAL",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "value": "SLIDER_TYPE_NORMAL",
            "text": "普通"
          },
          {
            "value": "SLIDER_TYPE_SYMMETRICAL",
            "text": "对称"
          },
          {
            "value": "SLIDER_TYPE_RANGE",
            "text": "范围"
          }
        ]
      }
    },
    {
      "title": "动画时长",
      "name": "animTime",
      "type": "Integer",
      "tip": "毫秒",
      "comType": "TiInputNum",
      "comConf": {
        "minValue": 0,
        "step": 100
      }
    },
    {
      "title": "控制柄模式",
      "name": "advHittest",
      "tip": "仅使用控制柄，点击指示器区域无效",
      "type": "Boolean",
      "comType": "TiToggle"
    }
  ],
  "comEvents": ["KEY_RIGHT", "KEY_LEFT", "VALUE_CHANGED"]
});
//========================================
// JOIN <lvgl-slider.html> com/lvgl/core/slider/lvgl-slider.html
//========================================
Ti.Preload("com/lvgl/core/slider/lvgl-slider.html", `<div class="lvgl-com-slider lvgl-inner-com-slider">
  <div class="slider-container" :style="containerStyle">
    <div class="part-bg" :style="PartBgStyle">
      <div class="part-indic" :style="PartIndicStyle">
      </div>
    </div>
    <div class="part-knob" :style="PartKnobStyle">
    </div>
  </div>
</div>`);
//========================================
// JOIN <lvgl-slider.mjs> com/lvgl/core/slider/lvgl-slider.mjs
//========================================
Ti.Preload("com/lvgl/core/slider/lvgl-slider.mjs", TI_PACK_EXPORTS['com/lvgl/core/slider/lvgl-slider.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/slider/_com.json
//========================================
Ti.Preload("com/lvgl/core/slider/_com.json", {
  "name": "LvglSlider",
  "globally": true,
  "template": "./lvgl-slider.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-slider.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/switch/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/switch/hmaker.json", {
  "icon": "fas-toggle-on",
  "title": "switch按钮",
  "measure": {
    "width": 60,
    "height": 30
  },
  "defaultPart": "BG",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "defaultStatus": {
      "bgPart": {},
      "indicPart": {},
      "knobPart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景"
    },
    {
      "value": "INDIC",
      "text": "指示器"
    },
    {
      "value": "KNOB",
      "text": "控制柄"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    }
  ],
  "indicPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    }
  ],
  "knobPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "内边距",
      "name": "partStyle.pad",
      "type": "Object",
      "comType": "LvglMakerStylePad"
    }
  ],
  "propFields": [
    {
      "title": "数据"
    },
    {
      "title": "状态",
      "name": "state",
      "type": "Boolean",
      "comType": "TiToggle"
    },
    {
      "title": "动画"
    },
    {
      "title": "打开动画",
      "name": "anim",
      "comType": "TiSwitcher",
      "comConf": {
        "options": ["ON", "OFF"]
      }
    },
    {
      "title": "动画时长",
      "name": "animTime",
      "type": "Integer",
      "width": 120,
      "visible": {
        "anim": "ON"
      },
      "comType": "TiInput",
      "comConf": {
        "suffixText": "ms"
      }
    }
  ],
  "comEvents": [
    "KEY_UP",
    "KEY_RIGHT",
    "KEY_DOWN",
    "KEY_LEFT",
    "KEY_ENTER",
    "VALUE_CHANGED"
  ]
});
//========================================
// JOIN <lvgl-switch.html> com/lvgl/core/switch/lvgl-switch.html
//========================================
Ti.Preload("com/lvgl/core/switch/lvgl-switch.html", `<div class="lvgl-com-switch lvgl-inner-com-slider">
  <div class="part-bg" :style="PartBgStyle">
    <div class="part-indic" :style="PartIndicStyle">
    </div>
  </div>
  <div class="part-knob" :style="PartKnobStyle">
  </div>
</div>`);
//========================================
// JOIN <lvgl-switch.mjs> com/lvgl/core/switch/lvgl-switch.mjs
//========================================
Ti.Preload("com/lvgl/core/switch/lvgl-switch.mjs", TI_PACK_EXPORTS['com/lvgl/core/switch/lvgl-switch.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/switch/_com.json
//========================================
Ti.Preload("com/lvgl/core/switch/_com.json", {
  "name": "LvglSwitch",
  "globally": true,
  "template": "./lvgl-switch.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-switch.mjs"
  ]
});
//========================================
// JOIN <hmaker.json> com/lvgl/core/textarea/hmaker.json
//========================================
Ti.Preload("com/lvgl/core/textarea/hmaker.json", {
  "icon": "zmdi-comment-alt-text",
  "title": "输入文字",
  "measure": {
    "width": 215,
    "height": 50
  },
  "defaultPart": "BG",
  "defaultStatus": "DEFAULT",
  "comConf": {
    "text": "",
    "placeholderText": "请输入内容",
    "oneLine": false,
    "cursorHidden": false,
    "pwdMode": false,
    "scrollbarMode": "OFF",
    "defaultStatus": {
      "bgPart": {
        "text": {
          "font": {
            "name": "SimSun",
            "size": 16,
            "weight": "NORMAL"
          }
        }
      },
      "cursorPart": {}
    }
  },
  "comTransition": false,
  "comStatus": [
    {
      "value": "DEFAULT",
      "text": "默认"
    }
  ],
  "comParts": [
    {
      "value": "BG",
      "text": "背景区域"
    },
    {
      "value": "CURSOR",
      "text": "光标区域"
    }
  ],
  "bgPartFields": [
    {
      "title": "背景样式",
      "name": "partStyle.bg",
      "type": "Object",
      "comType": "LvglMakerStyleBg"
    },
    {
      "title": "文字样式",
      "name": "partStyle.text",
      "type": "Object",
      "comType": "LvglMakerStyleText"
    }
  ],
  "cursorPartFields": [],
  "propFields": [
    {
      "title": "输入文字",
      "name": "text",
      "comType": "TiInputText"
    },
    {
      "title": "提示文字",
      "name": "placeholderText"
    },
    {
      "title": "隐藏光标",
      "name": "cursorHidden",
      "type": "Boolean",
      "comType": "TiToggle"
    },
    {
      "title": "光标闪烁时长",
      "name": "cursorBlinkTime",
      "type": "Number"
    },
    {
      "title": "单行模式",
      "name": "oneLine",
      "type": "Boolean",
      "comType": "TiToggle"
    },
    {
      "title": "密码模式",
      "name": "pwdMode",
      "type": "Boolean",
      "comType": "TiToggle"
    },
    {
      "title": "文本排列",
      "name": "align",
      "comType": "TiSwitcher",
      "comConf": {
        "options": [
          {
            "icon": "fas-align-left",
            "value": "LEFT",
            "tip": "居左"
          },
          {
            "icon": "fas-align-center",
            "value": "CENTER",
            "tip": "居中"
          },
          {
            "icon": "fas-align-right",
            "value": "RIGHT",
            "tip": "居右"
          }
        ]
      }
    },
    {
      "title": "可输入字符",
      "name": "acceptedChars"
    },
    {
      "title": "最大输入长度",
      "name": "maxLength",
      "type": "Number"
    },
    {
      "title": "超长文本",
      "name": "veryLongTexts",
      "type": "Boolean",
      "comType": "TiToggle"
    },
    {
      "title": "滚动条模式",
      "name": "scrollbarMode",
      "comType": "TiDroplist",
      "comConf": {
        "options": [
          {
            "value": "OFF",
            "text": "不显示"
          },
          {
            "value": "ON",
            "text": "一直显示"
          },
          {
            "value": "DRAG",
            "text": "拖动时显示"
          },
          {
            "value": "AUTO",
            "text": "自动显示"
          },
          {
            "value": "HIDE",
            "text": "临时隐藏"
          },
          {
            "value": "UNHIDE",
            "text": "临时隐藏恢复"
          }
        ]
      }
    },
    {
      "title": "滚动传播",
      "name": "scrollPropagation",
      "type": "Boolean",
      "comType": "TiToggle"
    }
  ],
  "comEvents": ["INSERT", "VALUE_CHANGED", "APPLY", "CLICKED"]
});
//========================================
// JOIN <lvgl-textarea.html> com/lvgl/core/textarea/lvgl-textarea.html
//========================================
Ti.Preload("com/lvgl/core/textarea/lvgl-textarea.html", `<div class="lvgl-com-textarea" :style="TopStyle">
  <textarea :type="pwdMode ? 'password':'text'" :value="text" :style="textareaStyle" :placeholder="placeholderText"
    disabled></textarea>
</div>`);
//========================================
// JOIN <lvgl-textarea.mjs> com/lvgl/core/textarea/lvgl-textarea.mjs
//========================================
Ti.Preload("com/lvgl/core/textarea/lvgl-textarea.mjs", TI_PACK_EXPORTS['com/lvgl/core/textarea/lvgl-textarea.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/core/textarea/_com.json
//========================================
Ti.Preload("com/lvgl/core/textarea/_com.json", {
  "name": "LvglTextarea",
  "globally": true,
  "template": "./lvgl-textarea.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/support/lvgl-com-support.mjs",
    "./lvgl-textarea.mjs"
  ]
});
//========================================
// JOIN <lvgl-maker-form-animat-val.html> com/lvgl/maker/form/animat-val/lvgl-maker-form-animat-val.html
//========================================
Ti.Preload("com/lvgl/maker/form/animat-val/lvgl-maker-form-animat-val.html", `<TiInput
  placeholder="请输入值"
  :value="InputVal"
  :suffixText="InputSuffixText"
  :hover="['suffixText']"
  @change="OnInputChange"
  @suffix:text="OnClickSuffixText"/>`);
//========================================
// JOIN <lvgl-maker-form-animat-val.mjs> com/lvgl/maker/form/animat-val/lvgl-maker-form-animat-val.mjs
//========================================
Ti.Preload("com/lvgl/maker/form/animat-val/lvgl-maker-form-animat-val.mjs", TI_PACK_EXPORTS['com/lvgl/maker/form/animat-val/lvgl-maker-form-animat-val.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/form/animat-val/_com.json
//========================================
Ti.Preload("com/lvgl/maker/form/animat-val/_com.json", {
  "name": "LvglMakerFormAnimatVal",
  "globally": true,
  "template": "./lvgl-maker-form-animat-val.html",
  "mixins": "./lvgl-maker-form-animat-val.mjs",
  "components": [
    "@com:ti/droplist"
  ]
});
//========================================
// JOIN <lvgl-maker-form-event.html> com/lvgl/maker/form/event/lvgl-maker-form-event.html
//========================================
Ti.Preload("com/lvgl/maker/form/event/lvgl-maker-form-event.html", `<div class="lvgl-maker-form-event full-field"> 
  <!--
    类型
  -->
  <div class="as-type">
    <TiDroplist
      :options="TypeOptions"
      :value="ValType"
      :display="['text','value::as-tip-block align-right']"
      :prefixIcon="null"
      dropWidth="1.2rem"
      @change="OnValTypeChange"/>
  </div>
  <!--
    名称
  -->
  <div class="as-name">
    <!--选择屏幕-->
    <TiDroplist
      v-if="'screen' == ValType"
        placeholder="选择屏幕"
        :options="ScreenNames"
        display="text"
        :value="ValName"
        @change="OnValNameChange"/>
    <!--函数调用-->
    <TiInput
      v-else
        placeholder="请输入函数名"
        prefixIcon="zmdi-close"
        :value="ValName"
        @change="OnValNameChange"/>
  </div>
</div>`);
//========================================
// JOIN <lvgl-maker-form-event.mjs> com/lvgl/maker/form/event/lvgl-maker-form-event.mjs
//========================================
Ti.Preload("com/lvgl/maker/form/event/lvgl-maker-form-event.mjs", TI_PACK_EXPORTS['com/lvgl/maker/form/event/lvgl-maker-form-event.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/form/event/_com.json
//========================================
Ti.Preload("com/lvgl/maker/form/event/_com.json", {
  "name": "LvglMakerFormEvent",
  "globally": true,
  "template": "./lvgl-maker-form-event.html",
  "mixins": "./lvgl-maker-form-event.mjs",
  "components": [
    "@com:ti/droplist"
  ]
});
//========================================
// JOIN <lvgl-example.json> com/lvgl/maker/lvgl-example.json
//========================================
Ti.Preload("com/lvgl/maker/lvgl-example.json", {
  "device": {
    "width": 640,
    "height": 480
  },
  "screens": [
    {
      "name": "ScreenA",
      "layout": {
        "type": "free",
        "blocks": [
          {
            "name": "BlockA",
            "width": 100,
            "height": 60,
            "x": 79,
            "y": 87,
            "body": "BlockA"
          },
          {
            "name": "BlockB",
            "width": 140,
            "height": 80,
            "x": 10,
            "y": 300,
            "body": "BlockB"
          }
        ]
      }
    },
    {
      "name": "ScreenB",
      "layout": {
        "type": "free",
        "blocks": [
          {
            "name": "BlockC",
            "width": 100,
            "height": 60,
            "x": 79,
            "y": 87,
            "body": "BlockC"
          },
          {
            "name": "BlockD",
            "width": 140,
            "height": 80,
            "x": 183,
            "y": 360,
            "body": "BlockD"
          },
          {
            "name": "BlockE",
            "width": 120,
            "height": 101,
            "x": 143,
            "y": 23,
            "body": "BlockE"
          }
        ]
      }
    }
  ],
  "schema": {
    "BlockA": {
      "comType": "LvglLabel",
      "comConf": {
        "text": "Label A"
      }
    },
    "BlockB": {
      "comType": "LvglArc",
      "comConf": {}
    },
    "BlockC": {
      "comType": "LvglButton",
      "comConf": {}
    },
    "BlockD": {
      "comType": "LvglLabel",
      "comConf": {
        "text": "Label D"
      }
    },
    "BlockE": {
      "comType": "LvglLabel",
      "comConf": {
        "text": "Label E"
      }
    }
  }
});
//========================================
// JOIN <lvgl-maker-com-loader.mjs> com/lvgl/maker/lvgl-maker-com-loader.mjs
//========================================
Ti.Preload("com/lvgl/maker/lvgl-maker-com-loader.mjs", TI_PACK_EXPORTS['com/lvgl/maker/lvgl-maker-com-loader.mjs']);
//========================================
// JOIN <lvgl-maker-menu.mjs> com/lvgl/maker/lvgl-maker-menu.mjs
//========================================
Ti.Preload("com/lvgl/maker/lvgl-maker-menu.mjs", TI_PACK_EXPORTS['com/lvgl/maker/lvgl-maker-menu.mjs']);
//========================================
// JOIN <lvgl-maker-preview.mjs> com/lvgl/maker/lvgl-maker-preview.mjs
//========================================
Ti.Preload("com/lvgl/maker/lvgl-maker-preview.mjs", TI_PACK_EXPORTS['com/lvgl/maker/lvgl-maker-preview.mjs']);
//========================================
// JOIN <lvgl-maker.html> com/lvgl/maker/lvgl-maker.html
//========================================
Ti.Preload("com/lvgl/maker/lvgl-maker.html", `<TiGui
  class="lvgl-maker"
  :layout="GUILayout"
  :schema="GUISchema"
  :shown="GUIShown"
  @select:block="OnSelectBlock"
  @select:screen="OnSelectScreen"
  @change:device="OnDeviceChange"
  @change:screen:name="OnCurrentScreenNameChange"
  @change:block:name="OnBlockNameChange"
  @change:block:prop="OnBlockPropChange"
  @change:block:props="OnBlockPropDataChange"
  @change:com:conf="OnCurrentComConfFieldChange"
  @change:com:conf:data="OnComConfChange"
  @toggle:block:visibility="OnToggleBlockVisibility"
  @remove:block:current="removeBlockFromScreen(myCurrentBlockName)"
  @insert:block="OnAddLvglCom"
  @lvgl:preview="OnPreviewLvgl"
  @toggle:outline:panel="OnToggleOutlinePanel"
  @block:hide="OnGuiBlockHide"
  @com:block:scale="OnComBlockScale"
  @com:block:resizable="OnComBlockResizable"
  @img:preloaded="OnStageImagePreloaded"/>`);
//========================================
// JOIN <lvgl-maker.mjs> com/lvgl/maker/lvgl-maker.mjs
//========================================
Ti.Preload("com/lvgl/maker/lvgl-maker.mjs", TI_PACK_EXPORTS['com/lvgl/maker/lvgl-maker.mjs']);
//========================================
// JOIN <lvgl-methods.mjs> com/lvgl/maker/lvgl-methods.mjs
//========================================
Ti.Preload("com/lvgl/maker/lvgl-methods.mjs", TI_PACK_EXPORTS['com/lvgl/maker/lvgl-methods.mjs']);
//========================================
// JOIN <lvgl-part-support.mjs> com/lvgl/maker/lvgl-part-support.mjs
//========================================
Ti.Preload("com/lvgl/maker/lvgl-part-support.mjs", TI_PACK_EXPORTS['com/lvgl/maker/lvgl-part-support.mjs']);
//========================================
// JOIN <mock-data.mjs> com/lvgl/maker/mock-data.mjs
//========================================
Ti.Preload("com/lvgl/maker/mock-data.mjs", TI_PACK_EXPORTS['com/lvgl/maker/mock-data.mjs']);
//========================================
// JOIN <lvgl-maker-outline.html> com/lvgl/maker/outline/lvgl-maker-outline.html
//========================================
Ti.Preload("com/lvgl/maker/outline/lvgl-maker-outline.html", `<div class="lvgl-maker-outline"> 
  <!--
    动作条
  -->
  <TiActionbar
    class="part-actions"
    :items="ActionItems"/>
  <!--
    列表
  -->
  <TiTree
    class="part-list"
    :data="LvglBlockOutlineTree"
    :display="LvglBlockDisplay"
    idBy="name"
    childrenBy="blocks"
    :multi="true"
    :checkable="true"
    :defaultOpenDepth="3"
    :currentId="currentBlockName"
    :checkedIds="checkedBlockNames"
    :puppetMode="true"
    :showRoot="false"
    :leafBy="IsBlockLeaf"
    :dftLabelHoverCopy="false"
    @select="OnSelectBlock"
    />
</div>`);
//========================================
// JOIN <lvgl-maker-outline.mjs> com/lvgl/maker/outline/lvgl-maker-outline.mjs
//========================================
Ti.Preload("com/lvgl/maker/outline/lvgl-maker-outline.mjs", TI_PACK_EXPORTS['com/lvgl/maker/outline/lvgl-maker-outline.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/outline/_com.json
//========================================
Ti.Preload("com/lvgl/maker/outline/_com.json", {
  "name": "LvglMakerOutline",
  "globally": true,
  "template": "./lvgl-maker-outline.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/maker/lvgl-part-support.mjs",
    "./lvgl-maker-outline.mjs"
  ],
  "components": [
    "@com:ti/tree"
  ]
});
//========================================
// JOIN <lvgl-maker-prop.html> com/lvgl/maker/prop/lvgl-maker-prop.html
//========================================
Ti.Preload("com/lvgl/maker/prop/lvgl-maker-prop.html", `<div class="lvgl-maker-prop"
  :class="TopClass"> 
  <!--
    显示设备和屏幕
  -->
  <TiForm
    v-if="isNil"
      class="ti-fill-parent"
      spacing="comfy"
      defaultComType="TiInput"
      bodyClass= "as-columns"
      :maxColumnHint="2"
      :autoColummGrid="[240,320,480]"
      :fields="DevFormFields"
      :data="DevFormData"
      :gridColumnHint="1"
      @field:change="OnDevFormFieldChange"/>
  <!--
    显示控件详情
  -->
  <template v-else>
    <!--
      选择控件
    -->
    <div class="as-head">
      <TiInput
        :prefixIcon="LvglCurrentComSetup.icon"
        :prefixText="LvglCurrentComSetup.title"
        :value="LvglCurrentBlock.name"
        @change="OnCurrentBlockNameChange"/>
    </div>
    <!--
      显示分类标签
    -->
    <div class="as-tabs">
      <TiSwitcher
        class="align-center"
        :options="ComFormList"
        :value="myFormName"
        :allowEmpty="false"
        @change="OnTabChange"/>
    </div>
    <!--
      当前的表单（尺寸/外观/属性/事件）
    -->
    <TiForm
      class="ti-fill-parent"
      spacing="comfy"
      mode="all"
      defaultComType="TiInput"
      v-bind="ComCurrentFormConf"
      :data="ComCurrentFormData"
      @field:change="OnComFormFieldChange"
      @change="OnFormChange"/>
  </template>
</div>`);
//========================================
// JOIN <lvgl-maker-prop.mjs> com/lvgl/maker/prop/lvgl-maker-prop.mjs
//========================================
Ti.Preload("com/lvgl/maker/prop/lvgl-maker-prop.mjs", TI_PACK_EXPORTS['com/lvgl/maker/prop/lvgl-maker-prop.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/prop/_com.json
//========================================
Ti.Preload("com/lvgl/maker/prop/_com.json", {
  "name": "LvglMakerProp",
  "globally": true,
  "template": "./lvgl-maker-prop.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/maker/lvgl-part-support.mjs",
    "./lvgl-maker-prop.mjs"
  ],
  "components": [
    "@com:ti/obj/pair",
    "@com:ti/combo/table",
    "@Site:com/lvgl/maker/form/event",
    "@Site:com/lvgl/maker/form/animat-val"
  ]
});
//========================================
// JOIN <stage-block.html> com/lvgl/maker/stage/com/stage-block/stage-block.html
//========================================
Ti.Preload("com/lvgl/maker/stage/com/stage-block/stage-block.html", `<div class="lvgl-maker-com-block" 
  :name="block.name"
  :class="TopClass"
  :style="TopStyle"
  :data-align="BlockAlignment"
  @click.left.stop="OnClickTop($event)"
  @dblclick.left.stop="OnDblClickTop">
  <!--
    嵌入式样式
  -->
  <div
    v-if="InlayStyleId"
      style="display:none"
      v-html="InlayStyleRule"></div>
  <!--
    主模块
  -->
  <div class="block-main" :style="MainStyle" :inlay-id="InlayStyleId">
    <!--
      所见即所得控件
    -->
    <component 
      v-if="block.comType"
        class="as-block-com"
        :style="SelfComStyle"
        :blockName="block.name"
        :is="block.comType"
        :width="myMea.width"
        :height="myMea.height"
        :widthReal="myMea.relW"
        :heightReal="myMea.relH"
        :projectId="projectId"
        :apiBase="apiBase"
        :zoomScale="zoomScale"
        :adjustLayout="AdjustLayout"
        v-bind="block.comConf"/>
    <!--
      提示信息
    -->
    <span
      v-if="block.comIcon"
        class="as-tip as-icon"><i :class="block.comIcon.className"></i></span>
    <span class="as-tip as-type">{{block.comName}}</span>
    <span class="as-tip as-name">{{block.name}}</span>
    <!--
      处理子节点
    -->
    <div
      v-if="block.hasChildren"
        class="as-com-con as-block-children"
        :style="ChildrenStyle">
        <div
          class="as-block-children-con" 
          :class="ChildrenConClass">
            <LvglMakerStageBlock
              v-for="child in block.blocks"
                class="as-sub-block"
                :isTopBlock="false"
                :style="ChildrenItemStyle"
                :key="child.name"
                :block="child"
                :parentLayout="block.layout"
                :parentAutoFit="block.autoFit"
                :viewportRect="block.rect"
                :projectId="projectId"
                :apiBase="apiBase"
                :zoomScale="zoomScale"/>
        </div>
    </div>
    <!--
      遮罩控制手柄
    -->
    <template v-if="block.current && !block.isAutoResize">
      <span class="as-hdl as-block" mode="NW"></span>
      <span class="as-hdl as-block" mode="NE"></span>
      <span class="as-hdl as-block" mode="SW"></span>
      <span class="as-hdl as-block" mode="SE"></span>
      <template v-if="block.isNSResize">
        <span class="as-hdl as-hbar" mode="N"></span>
        <span class="as-hdl as-hbar" mode="S"></span>
      </template>
      <template v-if="block.isEWResize">
        <span class="as-hdl as-vbar" mode="W"></span>
        <span class="as-hdl as-vbar" mode="E"></span>
      </template>
    </template>
  </div> <!--.block-main-->
</div>`);
//========================================
// JOIN <stage-block.mjs> com/lvgl/maker/stage/com/stage-block/stage-block.mjs
//========================================
Ti.Preload("com/lvgl/maker/stage/com/stage-block/stage-block.mjs", TI_PACK_EXPORTS['com/lvgl/maker/stage/com/stage-block/stage-block.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/stage/com/stage-block/_com.json
//========================================
Ti.Preload("com/lvgl/maker/stage/com/stage-block/_com.json", {
  "name": "LvglMakerStageBlock",
  "globally": false,
  "template": "./stage-block.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": "./stage-block.mjs",
  "components": []
});
//========================================
// JOIN <lvgl-maker-stage-crumb.mjs> com/lvgl/maker/stage/lvgl-maker-stage-crumb.mjs
//========================================
Ti.Preload("com/lvgl/maker/stage/lvgl-maker-stage-crumb.mjs", TI_PACK_EXPORTS['com/lvgl/maker/stage/lvgl-maker-stage-crumb.mjs']);
//========================================
// JOIN <lvgl-maker-stage.html> com/lvgl/maker/stage/lvgl-maker-stage.html
//========================================
Ti.Preload("com/lvgl/maker/stage/lvgl-maker-stage.html", `<div class="lvgl-maker-stage" :class="TopClass" v-ti-draggable="Draggable">
  <!--
    控件画布
  -->
  <div class="part-main" @click.left.stop="OnClickPartMain">
    <div class="part-main-w">
      <!--主区域-->
      <div class="part-main-con" ref="main">
        <div :class="'part-viewport r' + ViewportRotation" :style="ViewportStyle">

          <!-- 画布方向提示器 >
        <div :class="'part-viewport-rotation r' + ViewportRotation" :title="'当前旋转为' + ViewportRotation + '度'"
          v-show="showScreenRotation">
          屏幕上方</div-->

          <!--
          控件拖拽遮板
        -->
          <div class="as-com-wrapper">
            <div class="as-com-con">
              <LvglMakerStageBlock v-for="bi in ViewBlockItems" :key="bi.name" :block="bi" :viewportRect="device"
                :projectId="projectId" :apiBase="apiBase" :zoomScale="myZoomScale"
                @select:block="OnSelectBlockItem($event)" />
            </div>
            <!--.as-com-con-->
          </div>
          <!--.as-com-wrapper-->
        </div> <!-- .part-viewport -->
      </div> <!-- .part-main-con -->
      <!--面包屑-->
      <div class="part-top-crumb">
        <TiCrumb :data="StageCrumbData" @item:active="OnCrumbItemActived"/>
      </div>
      <!--提示文字-->
      <div class="part-right-tip">
        <span>{{StageComCheckTip}}</span>
        <template v-if="StageInDragging">
          <i class="fas fa-mouse"></i>
        </template>
        <template v-if="blockScale > 0">
          <span>控件比例</span><em>{{blockScale}}</em>
        </template>
      </div>
    </div>
    <!--.part-main-w-->
  </div>
  <!--.part-main-->
  <!--
    组件大纲视图
  -->
  <div class="part-abar">
    <!-- 缩放比例 -->
    <div class="abar-text is-zoom-val"><em>{{zoomVal}}%</em></div>
    <!--模拟器-->
    <div v-if="showPreviewButton" class="abar-item is-preview-btn" @click.stop="OnClickPreviewButton">
      <i class="zmdi zmdi-dock"></i>
    </div>
    <!--大纲-->
    <div class="abar-item is-outline-panel" @click.left="OnToggleOutlinePanel">
      <i class="fas fa-sitemap"></i>
    </div>
  </div>
  <!--
    底部 Screen 列表
  -->
  <div class="part-screens">
    <div class="as-screen-list">
      <div v-for="screen in LvglScreenNames" class="as-screen-item" :class="screen.className"
        @click.left="OnScreenChange(screen.value)"><span>{{screen.text}}</span>
      </div>
    </div>
  </div>
</div>`);
//========================================
// JOIN <lvgl-maker-stage.mjs> com/lvgl/maker/stage/lvgl-maker-stage.mjs
//========================================
Ti.Preload("com/lvgl/maker/stage/lvgl-maker-stage.mjs", TI_PACK_EXPORTS['com/lvgl/maker/stage/lvgl-maker-stage.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/stage/_com.json
//========================================
Ti.Preload("com/lvgl/maker/stage/_com.json", {
  "name": "LvglMakerStage",
  "globally": true,
  "template": "./lvgl-maker-stage.html",
  "methods": "@Site:com/lvgl/maker/lvgl-methods.mjs",
  "mixins": [
    "@Site:com/lvgl/maker/lvgl-part-support.mjs",
    "./lvgl-maker-stage-crumb.mjs",
    "./lvgl-maker-stage.mjs"
  ],
  "components": [
    "./com/stage-block",
    "@com:ti/crumb",
    "@Site:com/lvgl/core/arc",
    "@Site:com/lvgl/core/bar",
    "@Site:com/lvgl/core/btnmatrix",
    "@Site:com/lvgl/core/button",
    "@Site:com/lvgl/core/calendar",
    "@Site:com/lvgl/core/cb",
    "@Site:com/lvgl/core/chart",
    "@Site:com/lvgl/core/cpicker",
    "@Site:com/lvgl/core/dropdown",
    "@Site:com/lvgl/core/gauge",
    "@Site:com/lvgl/core/img",
    "@Site:com/lvgl/core/imgbtn",
    "@Site:com/lvgl/core/keyboard",
    "@Site:com/lvgl/core/label",
    "@Site:com/lvgl/core/led",
    "@Site:com/lvgl/core/switch",
    "@Site:com/lvgl/core/textarea"
  ]
});
//========================================
// JOIN <lvgl-maker-style-bg.html> com/lvgl/maker/style/bg/lvgl-maker-style-bg.html
//========================================
Ti.Preload("com/lvgl/maker/style/bg/lvgl-maker-style-bg.html", `<HmPropCssRules
  class="lvgl-maker-style is-lvgl-bg"
  keyType="camel"
  :autoI18nRuleTitle="false"
  :value="value"
  :form="StyleForm"/>`);
//========================================
// JOIN <lvgl-maker-style-bg.mjs> com/lvgl/maker/style/bg/lvgl-maker-style-bg.mjs
//========================================
Ti.Preload("com/lvgl/maker/style/bg/lvgl-maker-style-bg.mjs", TI_PACK_EXPORTS['com/lvgl/maker/style/bg/lvgl-maker-style-bg.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/style/bg/_com.json
//========================================
Ti.Preload("com/lvgl/maker/style/bg/_com.json", {
  "name": "LvglMakerStyleBg",
  "globally": true,
  "template": "./lvgl-maker-style-bg.html",
  "mixins": [
    "./lvgl-maker-style-bg.mjs"
  ]
});
//========================================
// JOIN <lvgl-maker-style-border.html> com/lvgl/maker/style/border/lvgl-maker-style-border.html
//========================================
Ti.Preload("com/lvgl/maker/style/border/lvgl-maker-style-border.html", `<HmPropCssRules
  class="lvgl-maker-style is-lvgl-border"
  keyType="camel"
  :autoI18nRuleTitle="false"
  :value="value"
  :form="StyleForm"/>`);
//========================================
// JOIN <lvgl-maker-style-border.mjs> com/lvgl/maker/style/border/lvgl-maker-style-border.mjs
//========================================
Ti.Preload("com/lvgl/maker/style/border/lvgl-maker-style-border.mjs", TI_PACK_EXPORTS['com/lvgl/maker/style/border/lvgl-maker-style-border.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/style/border/_com.json
//========================================
Ti.Preload("com/lvgl/maker/style/border/_com.json", {
  "name": "LvglMakerStyleBorder",
  "globally": true,
  "template": "./lvgl-maker-style-border.html",
  "mixins": [
    "./lvgl-maker-style-border.mjs"
  ]
});
//========================================
// JOIN <lvgl-maker-style-line.html> com/lvgl/maker/style/line/lvgl-maker-style-line.html
//========================================
Ti.Preload("com/lvgl/maker/style/line/lvgl-maker-style-line.html", `<HmPropCssRules
  class="lvgl-maker-style is-lvgl-line"
  keyType="camel"
  :autoI18nRuleTitle="false"
  :value="value"
  :form="StyleForm"/>`);
//========================================
// JOIN <lvgl-maker-style-line.mjs> com/lvgl/maker/style/line/lvgl-maker-style-line.mjs
//========================================
Ti.Preload("com/lvgl/maker/style/line/lvgl-maker-style-line.mjs", TI_PACK_EXPORTS['com/lvgl/maker/style/line/lvgl-maker-style-line.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/style/line/_com.json
//========================================
Ti.Preload("com/lvgl/maker/style/line/_com.json", {
  "name": "LvglMakerStyleLine",
  "globally": true,
  "template": "./lvgl-maker-style-line.html",
  "mixins": [
    "./lvgl-maker-style-line.mjs"
  ]
});
//========================================
// JOIN <lvgl-maker-style-margin.html> com/lvgl/maker/style/margin/lvgl-maker-style-margin.html
//========================================
Ti.Preload("com/lvgl/maker/style/margin/lvgl-maker-style-margin.html", `<HmPropCssRules
  class="lvgl-maker-style is-lvgl-margin"
  keyType="camel"
  :autoI18nRuleTitle="false"
  :value="value"
  :form="StyleForm"/>`);
//========================================
// JOIN <lvgl-maker-style-margin.mjs> com/lvgl/maker/style/margin/lvgl-maker-style-margin.mjs
//========================================
Ti.Preload("com/lvgl/maker/style/margin/lvgl-maker-style-margin.mjs", TI_PACK_EXPORTS['com/lvgl/maker/style/margin/lvgl-maker-style-margin.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/style/margin/_com.json
//========================================
Ti.Preload("com/lvgl/maker/style/margin/_com.json", {
  "name": "LvglMakerStyleMargin",
  "globally": true,
  "template": "./lvgl-maker-style-margin.html",
  "mixins": [
    "./lvgl-maker-style-margin.mjs"
  ]
});
//========================================
// JOIN <lvgl-maker-style-outline.html> com/lvgl/maker/style/outline/lvgl-maker-style-outline.html
//========================================
Ti.Preload("com/lvgl/maker/style/outline/lvgl-maker-style-outline.html", `<HmPropCssRules
  class="lvgl-maker-style is-lvgl-outline"
  keyType="camel"
  :autoI18nRuleTitle="false"
  :value="value"
  :form="StyleForm"/>`);
//========================================
// JOIN <lvgl-maker-style-outline.mjs> com/lvgl/maker/style/outline/lvgl-maker-style-outline.mjs
//========================================
Ti.Preload("com/lvgl/maker/style/outline/lvgl-maker-style-outline.mjs", TI_PACK_EXPORTS['com/lvgl/maker/style/outline/lvgl-maker-style-outline.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/style/outline/_com.json
//========================================
Ti.Preload("com/lvgl/maker/style/outline/_com.json", {
  "name": "LvglMakerStyleOutline",
  "globally": true,
  "template": "./lvgl-maker-style-outline.html",
  "mixins": [
    "./lvgl-maker-style-outline.mjs"
  ]
});
//========================================
// JOIN <lvgl-maker-style-pad.html> com/lvgl/maker/style/pad/lvgl-maker-style-pad.html
//========================================
Ti.Preload("com/lvgl/maker/style/pad/lvgl-maker-style-pad.html", `<HmPropCssRules
  class="lvgl-maker-style is-lvgl-pad"
  keyType="camel"
  :autoI18nRuleTitle="false"
  :value="value"
  :form="StyleForm"/>`);
//========================================
// JOIN <lvgl-maker-style-pad.mjs> com/lvgl/maker/style/pad/lvgl-maker-style-pad.mjs
//========================================
Ti.Preload("com/lvgl/maker/style/pad/lvgl-maker-style-pad.mjs", TI_PACK_EXPORTS['com/lvgl/maker/style/pad/lvgl-maker-style-pad.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/style/pad/_com.json
//========================================
Ti.Preload("com/lvgl/maker/style/pad/_com.json", {
  "name": "LvglMakerStylePad",
  "globally": true,
  "template": "./lvgl-maker-style-pad.html",
  "mixins": [
    "./lvgl-maker-style-pad.mjs"
  ]
});
//========================================
// JOIN <lvgl-maker-style-shadow.html> com/lvgl/maker/style/shadow/lvgl-maker-style-shadow.html
//========================================
Ti.Preload("com/lvgl/maker/style/shadow/lvgl-maker-style-shadow.html", `<HmPropCssRules
  class="lvgl-maker-style is-lvgl-shadow"
  keyType="camel"
  :autoI18nRuleTitle="false"
  :value="value"
  :form="StyleForm"/>`);
//========================================
// JOIN <lvgl-maker-style-shadow.mjs> com/lvgl/maker/style/shadow/lvgl-maker-style-shadow.mjs
//========================================
Ti.Preload("com/lvgl/maker/style/shadow/lvgl-maker-style-shadow.mjs", TI_PACK_EXPORTS['com/lvgl/maker/style/shadow/lvgl-maker-style-shadow.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/style/shadow/_com.json
//========================================
Ti.Preload("com/lvgl/maker/style/shadow/_com.json", {
  "name": "LvglMakerStyleShadow",
  "globally": true,
  "template": "./lvgl-maker-style-shadow.html",
  "mixins": [
    "./lvgl-maker-style-shadow.mjs"
  ]
});
//========================================
// JOIN <lvgl-maker-style-text.html> com/lvgl/maker/style/text/lvgl-maker-style-text.html
//========================================
Ti.Preload("com/lvgl/maker/style/text/lvgl-maker-style-text.html", `<HmPropCssRules
  class="lvgl-maker-style is-lvgl-text"
  keyType="camel"
  :autoI18nRuleTitle="false"
  :value="value"
  :form="StyleForm"/>`);
//========================================
// JOIN <lvgl-maker-style-text.mjs> com/lvgl/maker/style/text/lvgl-maker-style-text.mjs
//========================================
Ti.Preload("com/lvgl/maker/style/text/lvgl-maker-style-text.mjs", TI_PACK_EXPORTS['com/lvgl/maker/style/text/lvgl-maker-style-text.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/style/text/_com.json
//========================================
Ti.Preload("com/lvgl/maker/style/text/_com.json", {
  "name": "LvglMakerStyleText",
  "globally": true,
  "template": "./lvgl-maker-style-text.html",
  "mixins": [
    "./lvgl-maker-style-text.mjs"
  ]
});
//========================================
// JOIN <lvgl-maker-style-transition.html> com/lvgl/maker/style/transition/lvgl-maker-style-transition.html
//========================================
Ti.Preload("com/lvgl/maker/style/transition/lvgl-maker-style-transition.html", `<HmPropCssRules
  class="lvgl-maker-style is-lvgl-transition"
  keyType="camel"
  :autoI18nRuleTitle="false"
  :value="value"
  :dialog="{height:'4.8rem'}"
  :form="StyleForm"/>`);
//========================================
// JOIN <lvgl-maker-style-transition.mjs> com/lvgl/maker/style/transition/lvgl-maker-style-transition.mjs
//========================================
Ti.Preload("com/lvgl/maker/style/transition/lvgl-maker-style-transition.mjs", TI_PACK_EXPORTS['com/lvgl/maker/style/transition/lvgl-maker-style-transition.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/style/transition/_com.json
//========================================
Ti.Preload("com/lvgl/maker/style/transition/_com.json", {
  "name": "LvglMakerStyleTransition",
  "globally": true,
  "template": "./lvgl-maker-style-transition.html",
  "mixins": [
    "./lvgl-maker-style-transition.mjs"
  ]
});
//========================================
// JOIN <lvgl-maker-style-value.html> com/lvgl/maker/style/value/lvgl-maker-style-value.html
//========================================
Ti.Preload("com/lvgl/maker/style/value/lvgl-maker-style-value.html", `<HmPropCssRules
  class="lvgl-maker-style is-lvgl-value"
  keyType="camel"
  :autoI18nRuleTitle="false"
  :value="value"
  :form="StyleForm"/>`);
//========================================
// JOIN <lvgl-maker-style-value.mjs> com/lvgl/maker/style/value/lvgl-maker-style-value.mjs
//========================================
Ti.Preload("com/lvgl/maker/style/value/lvgl-maker-style-value.mjs", TI_PACK_EXPORTS['com/lvgl/maker/style/value/lvgl-maker-style-value.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/maker/style/value/_com.json
//========================================
Ti.Preload("com/lvgl/maker/style/value/_com.json", {
  "name": "LvglMakerStyleValue",
  "globally": true,
  "template": "./lvgl-maker-style-value.html",
  "mixins": [
    "./lvgl-maker-style-value.mjs"
  ]
});
//========================================
// JOIN <_com.json> com/lvgl/maker/_com.json
//========================================
Ti.Preload("com/lvgl/maker/_com.json", {
  "name": "LvglMaker",
  "globally": true,
  "template": "./lvgl-maker.html",
  "mixins": [
    "./lvgl-maker-com-loader.mjs",
    "./lvgl-maker.mjs",
    "./lvgl-maker-preview.mjs",
    "./lvgl-maker-menu.mjs"
  ],
  "components": [
    "./prop",
    "./stage",
    "./outline",
    "./style/bg",
    "./style/border",
    "./style/line",
    "./style/margin",
    "./style/outline",
    "./style/pad",
    "./style/shadow",
    "./style/text",
    "./style/transition",
    "./style/value",
    "@com:hm/prop/css-rules"
  ]
});
//========================================
// JOIN <lvgl-simulator.html> com/lvgl/simulator/lvgl-simulator.html
//========================================
Ti.Preload("com/lvgl/simulator/lvgl-simulator.html", `<div class="lvgl-simulator">
  <!--左侧模拟器-->
  <div class="as-main">
    <WebWidgetFrame
      v-if="iAmReady"
        :src="frameSrc"
        width="100%"
        height="100%"
        :postEvents="FramePostEvents"
        :postPayload="FramePostPayload"/>
  </div>
  <!--右侧日志面板-->
  <div class="as-logs" ref="logs">
    <div
      v-for="(log, index) in myLogs"
        :key="index"
        class="log-line">
        {{log.text}}
    </div>
  </div>
</div>`);
//========================================
// JOIN <lvgl-simulator.mjs> com/lvgl/simulator/lvgl-simulator.mjs
//========================================
Ti.Preload("com/lvgl/simulator/lvgl-simulator.mjs", TI_PACK_EXPORTS['com/lvgl/simulator/lvgl-simulator.mjs']);
//========================================
// JOIN <_com.json> com/lvgl/simulator/_com.json
//========================================
Ti.Preload("com/lvgl/simulator/_com.json", {
  "name": "LvglSimulator",
  "globally": true,
  "template": "./lvgl-simulator.html",
  "mixins": "./lvgl-simulator.mjs",
  "components": [
    "@com:web/widget/frame"
  ]
});
//========================================
// JOIN <lvgl-com-support.mjs> com/lvgl/support/lvgl-com-support.mjs
//========================================
Ti.Preload("com/lvgl/support/lvgl-com-support.mjs", TI_PACK_EXPORTS['com/lvgl/support/lvgl-com-support.mjs']);
//========================================
// JOIN <page-footer.html> com/page/footer/page-footer.html
//========================================
Ti.Preload("com/page/footer/page-footer.html", `<div class="page-footer"
  :class="TopClass"> 
  <div style="text-align: right; padding:0 .2rem;">
    <a href="/en_us/page/home.html">English</a>
    | <a href="/zh_cn/page/home.html">中文</a>
  </div>
  <!--
    Sloagan
  -->
  <div class="page-section as-slogan">
    {{'lu-foot-slogan'|i18n}}
  </div>
  <!--
    Logo
  -->
  <div class="page-section as-logo">
    <img :src="LogoSrc"/>
  </div>
  <!--
    Copyright
  -->
  <div class="page-section as-copyright">
    LuatOS Team &copy; 2021
    <br><br>
    <a href="http://beian.miit.gov.cn/" target="_blank">皖ICP备2020020577号</a>
  </div>
</div>`);
//========================================
// JOIN <page-footer.mjs> com/page/footer/page-footer.mjs
//========================================
Ti.Preload("com/page/footer/page-footer.mjs", TI_PACK_EXPORTS['com/page/footer/page-footer.mjs']);
//========================================
// JOIN <_com.json> com/page/footer/_com.json
//========================================
Ti.Preload("com/page/footer/_com.json", {
  "name" : "luo-page-footer",
  "globally" : true,
  "inject": {
    "apiBase" : {"default" : "/api"},
    "cdnTmpl" : {"default" : null}, 
    "base"    : {"default" : "/"}
  },
  "template" : "./page-footer.html",
  "mixins" : ["./page-footer.mjs"]
});
//========================================
// JOIN <luo-tile-device.html> com/tile/device/luo-tile-device.html
//========================================
Ti.Preload("com/tile/device/luo-tile-device.html", `<div class="luo-tile-device"
  :class="TopClass"> 
  <!--
    设备左侧信息
  -->
  <div class="dev-left">
    <TiIcon value="fas-microchip"/>
  </div>
  <!--
    设备中段信息
  -->
  <div class="dev-main">
    <!--
      设备摘要信息
    -->
    <div class="dev-info">
      <div class="dev-k-nm">{{Dev.nm}}</div>
      <div class="dev-k-title">{{Dev.title}}</div>
    </div>
  </div>
  <!--
    删除操作
  -->
  <!--
    设备操作
  -->
  <div class="dev-actions">
    <!--日志-->
    <a 
      :href="LogPageHref"
      target="_blank">
      <i class="fas fa-file-alt"></i> 查看日志</a>
    <!--轨迹-->
    <a
      :href="TrackPageHref">
      <i class="fas fa-map-marked-alt"></i> 查看轨迹</a>
    <!--删除-->
    <a 
      class="as-remove"
      @click.left="OnClickRemove"><i class="far fa-trash-alt"></i></a>
  </div>
</div>`);
//========================================
// JOIN <luo-tile-device.mjs> com/tile/device/luo-tile-device.mjs
//========================================
Ti.Preload("com/tile/device/luo-tile-device.mjs", TI_PACK_EXPORTS['com/tile/device/luo-tile-device.mjs']);
//========================================
// JOIN <_com.json> com/tile/device/_com.json
//========================================
Ti.Preload("com/tile/device/_com.json", {
  "name" : "luo-tile-device",
  "globally" : true,
  "inject": {
    "apiBase" : {"default" : "/api"},
    "cdnTmpl" : {"default" : null}, 
    "base"    : {"default" : "/"}
  },
  "template" : "./luo-tile-device.html",
  "mixins" : ["./luo-tile-device.mjs"]
});
//========================================
// JOIN <luo-tile-devlog.html> com/tile/devlog/luo-tile-devlog.html
//========================================
Ti.Preload("com/tile/devlog/luo-tile-devlog.html", `<div class="luo-tile-devlog"
  :class="TopClass"> 
  <!--
    设备摘要信息
  -->
  <div class="as-info">
    <div class="as-item is-ct">
      <span>{{Log.createTime}}</span>
    </div>
    <div class="as-item is-dev">
      <span>{{Log.dev}}</span>
    </div>
    <div class="as-item is-devsn">
      <span>{{Log.devsn}}</span>
    </div>
    <div class="as-item is-ipaddr">
      <span>{{Log.ipaddr}}</span>
    </div>
    <div class="as-item is-selfver">
      <b>自</b>
      <span>{{Log.selfver}}</span>
    </div>
    <div class="as-item is-lodver">
      <b>固</b>
      <span>{{Log.lodver}}</span>
    </div>
  </div>
  <!--
    设备日志详情
  -->
  <div class="as-log">
<pre>{{Log.poweron}}
{{Log.errlog}}</pre>
  </div>
</div>`);
//========================================
// JOIN <luo-tile-devlog.mjs> com/tile/devlog/luo-tile-devlog.mjs
//========================================
Ti.Preload("com/tile/devlog/luo-tile-devlog.mjs", TI_PACK_EXPORTS['com/tile/devlog/luo-tile-devlog.mjs']);
//========================================
// JOIN <_com.json> com/tile/devlog/_com.json
//========================================
Ti.Preload("com/tile/devlog/_com.json", {
  "name" : "luo-tile-devlog",
  "globally" : true,
  "inject": {
    "apiBase" : {"default" : "/api"},
    "cdnTmpl" : {"default" : null}, 
    "base"    : {"default" : "/"}
  },
  "template" : "./luo-tile-devlog.html",
  "mixins" : ["./luo-tile-devlog.mjs"]
});
//========================================
// JOIN <wb-arena.html> com/workbench/com/wb-arena/wb-arena.html
//========================================
Ti.Preload("com/workbench/com/wb-arena/wb-arena.html", `<div class="wb-block as-arena"> 
  <!--
    显示空白
  -->
  <TiLoading
    v-if="isEmpty"
      text="请选择要编辑的项目"
      icon="fas-arrow-left"/>
  <!--
    显示文件列表
  -->
  <TiAdaptlist
    v-else-if="isDIR"
      :meta="meta"
      :data="list"
      :currentId="currentId"
      :checkedIds="checkedIds"
      :uploadBy="FileUploadBy"
      :thumbBy="FileThumbBy"
      acceptUpload="jpg,jpeg,png"
      :routers="AdaptListRounters"
      @open:obj="OnOpenImage"/>
  <!--
    显示 LVGL 编辑器
  -->
  <LvglMaker
    v-else-if="isLVGL"
      :value="content"
      :apiBase="apiBase"
      :projectId="projectId"/>
  <!--
    显示源代码编辑器
  -->
  <TiTextCodeAce
    v-else
      :value="content"
      mode="lua"/>
</div>`);
//========================================
// JOIN <wb-arena.mjs> com/workbench/com/wb-arena/wb-arena.mjs
//========================================
Ti.Preload("com/workbench/com/wb-arena/wb-arena.mjs", TI_PACK_EXPORTS['com/workbench/com/wb-arena/wb-arena.mjs']);
//========================================
// JOIN <_com.json> com/workbench/com/wb-arena/_com.json
//========================================
Ti.Preload("com/workbench/com/wb-arena/_com.json", {
  "name" : "WorkbenchArena",
  "globally" : false,
  "inject": {
    "apiBase" : {"default" : "/api"},
    "cdnTmpl" : {"default" : null}, 
    "base"    : {"default" : "/"}
  },
  "template" : "./wb-arena.html",
  "mixins" : ["./wb-arena.mjs"],
  "components" : [
    "@com:ti/text/code/ace",
    "@com:ti/adaptlist",
    "@Site:com/lvgl/maker"
  ]
});
//========================================
// JOIN <wb-devices.html> com/workbench/com/wb-devices/wb-devices.html
//========================================
Ti.Preload("com/workbench/com/wb-devices/wb-devices.html", `<div class="wb-block as-devices"> 
  <!--
    头部
  -->
  <header>
    <h4>外部设备</h4>
    <div class="as-menu">
      <a>添加设备</a>
    </div>
  </header>
  <!--
    列表
  -->
  <section>
    暂无设备
  </section>
</div>`);
//========================================
// JOIN <wb-devices.mjs> com/workbench/com/wb-devices/wb-devices.mjs
//========================================
Ti.Preload("com/workbench/com/wb-devices/wb-devices.mjs", TI_PACK_EXPORTS['com/workbench/com/wb-devices/wb-devices.mjs']);
//========================================
// JOIN <_com.json> com/workbench/com/wb-devices/_com.json
//========================================
Ti.Preload("com/workbench/com/wb-devices/_com.json", {
  "name" : "WorkbenchDevices",
  "globally" : false,
  "template" : "./wb-devices.html",
  "mixins" : ["./wb-devices.mjs"]
});
//========================================
// JOIN <wb-imports.html> com/workbench/com/wb-imports/wb-imports.html
//========================================
Ti.Preload("com/workbench/com/wb-imports/wb-imports.html", `<div class="wb-block as-imports as-file-tree"> 
  <!--
    列表
  -->
  <section>

  </section>
</div>
</div>`);
//========================================
// JOIN <wb-imports.mjs> com/workbench/com/wb-imports/wb-imports.mjs
//========================================
Ti.Preload("com/workbench/com/wb-imports/wb-imports.mjs", TI_PACK_EXPORTS['com/workbench/com/wb-imports/wb-imports.mjs']);
//========================================
// JOIN <_com.json> com/workbench/com/wb-imports/_com.json
//========================================
Ti.Preload("com/workbench/com/wb-imports/_com.json", {
  "name" : "WorkbenchImports",
  "globally" : false,
  "template" : "./wb-imports.html",
  "mixins" : ["./wb-imports.mjs"]
});
//========================================
// JOIN <wb-mcu.html> com/workbench/com/wb-mcu/wb-mcu.html
//========================================
Ti.Preload("com/workbench/com/wb-mcu/wb-mcu.html", `<div class="wb-block as-mcu"> 
  <!--头部-->
  <header>
    <h4>请选择一个模块类型</h4>
    <div class="as-menu">
      <a>选择</a>
    </div>
  </header>
  <!--主控按钮-->
  <section>
    <!--按钮：运行-->
    <div class="as-btn is-run">
      <i class="fas fa-play-circle"></i>
      <span>运行</span>
    </div>
    <!--按钮：停止-->
    <div class="as-btn is-stop">
      <i class="fas fa-stop-circle"></i>
      <span>停止</span>
    </div>
    <!--按钮：生成-->
    <div class="as-btn is-build">
      <i class="fas fa-hammer"></i>
      <span>生成</span>
    </div>
  </section>
</div>`);
//========================================
// JOIN <wb-mcu.mjs> com/workbench/com/wb-mcu/wb-mcu.mjs
//========================================
Ti.Preload("com/workbench/com/wb-mcu/wb-mcu.mjs", TI_PACK_EXPORTS['com/workbench/com/wb-mcu/wb-mcu.mjs']);
//========================================
// JOIN <_com.json> com/workbench/com/wb-mcu/_com.json
//========================================
Ti.Preload("com/workbench/com/wb-mcu/_com.json", {
  "name" : "WorkbenchMcu",
  "globally" : false,
  "template" : "./wb-mcu.html",
  "mixins" : ["./wb-mcu.mjs"]
});
//========================================
// JOIN <wb-source-tree.html> com/workbench/com/wb-source-tree/wb-source-tree.html
//========================================
Ti.Preload("com/workbench/com/wb-source-tree/wb-source-tree.html", `<TiTree
    class="wb-block as-source as-file-tree"
    :data="data"
    :currentId="currentId"
    id-by="id"
    name-by="nm"
    children-by="children"
    :display="TreeDisplay"

    :opened-node-paths="myOpenedNodePaths"
    
    :auto-open="false"
    :show-root="false"
    :multi="false"
    
    :checkable="false"
    :selectable="true"
    :cancelable="true"
    :openable="true"
    :hoverable="false"

    spacing="comfy"
    border="row"
    height="100%"
    :leaf-by="{race:'![BLANK]'}"
    :on-init="OnTreeInit"
    @opened="OnNodeOpened"
    @opened-status:changed="OnTreeOpenedStatusChange"/>`);
//========================================
// JOIN <wb-source-tree.mjs> com/workbench/com/wb-source-tree/wb-source-tree.mjs
//========================================
Ti.Preload("com/workbench/com/wb-source-tree/wb-source-tree.mjs", TI_PACK_EXPORTS['com/workbench/com/wb-source-tree/wb-source-tree.mjs']);
//========================================
// JOIN <_com.json> com/workbench/com/wb-source-tree/_com.json
//========================================
Ti.Preload("com/workbench/com/wb-source-tree/_com.json", {
  "name" : "WorkbenchSourceTree",
  "globally" : false,
  "template" : "./wb-source-tree.html",
  "mixins" : ["./wb-source-tree.mjs"],
  "components" : [
    "@com:ti/tree"
  ]
});
//========================================
// JOIN <wb-head.html> com/workbench/head/wb-head.html
//========================================
Ti.Preload("com/workbench/head/wb-head.html", `<div class="luo-workbench-head"> 
  <div class="as-title"><a href="../page/home.html">{{'i18n:home-index'|i18n}}</a></div>
  <div class="as-sep"><i class="fas fa-chevron-right"></i></div>
  <template v-if="hasProject">
    <!--
      项目图标
    -->
    <TiIcon :value="ProjectIcon"/>
    <!--
      项目标题
    -->
    <div class="as-title">{{ProjectTitle}}</div>
  </template>
  <template v-if="hasFile">
    <div class="as-sep"><i class="fas fa-chevron-right"></i></div>
    <div class="as-file">{{FileName}}</div>
  </template>
</div>`);
//========================================
// JOIN <wb-head.mjs> com/workbench/head/wb-head.mjs
//========================================
Ti.Preload("com/workbench/head/wb-head.mjs", TI_PACK_EXPORTS['com/workbench/head/wb-head.mjs']);
//========================================
// JOIN <_com.json> com/workbench/head/_com.json
//========================================
Ti.Preload("com/workbench/head/_com.json", {
  "name" : "luo-workbench-head",
  "globally" : true,
  "inject": {
    "apiBase" : {"default" : "/api"},
    "cdnTmpl" : {"default" : null}, 
    "base"    : {"default" : "/"}
  },
  "template" : "./wb-head.html",
  "mixins" : ["./wb-head.mjs"],
  "components": [
    
  ]
});
//========================================
// JOIN <workbench-computed.mjs> com/workbench/workbench-computed.mjs
//========================================
Ti.Preload("com/workbench/workbench-computed.mjs", TI_PACK_EXPORTS['com/workbench/workbench-computed.mjs']);
//========================================
// JOIN <workbench-global-imports.mjs> com/workbench/workbench-global-imports.mjs
//========================================
Ti.Preload("com/workbench/workbench-global-imports.mjs", TI_PACK_EXPORTS['com/workbench/workbench-global-imports.mjs']);
//========================================
// JOIN <workbench-methods.mjs> com/workbench/workbench-methods.mjs
//========================================
Ti.Preload("com/workbench/workbench-methods.mjs", TI_PACK_EXPORTS['com/workbench/workbench-methods.mjs']);
//========================================
// JOIN <workbench-source-tree.mjs> com/workbench/workbench-source-tree.mjs
//========================================
Ti.Preload("com/workbench/workbench-source-tree.mjs", TI_PACK_EXPORTS['com/workbench/workbench-source-tree.mjs']);
//========================================
// JOIN <workbench.html> com/workbench/workbench.html
//========================================
Ti.Preload("com/workbench/workbench.html", `<TiGui
  class="luo-workbench"
  :layout="TheLayout"
  :schema="TheSchema"
  __@tree::select="OnTreeSelect"/>`);
//========================================
// JOIN <workbench.mjs> com/workbench/workbench.mjs
//========================================
Ti.Preload("com/workbench/workbench.mjs", TI_PACK_EXPORTS['com/workbench/workbench.mjs']);
//========================================
// JOIN <_com.json> com/workbench/_com.json
//========================================
Ti.Preload("com/workbench/_com.json", {
  "name" : "luo-workbench",
  "globally" : true,
  "inject": {
    "apiBase" : {"default" : "/api"},
    "cdnTmpl" : {"default" : null}, 
    "base"    : {"default" : "/"}
  },
  "template" : "./workbench.html",
  "computed" : "./workbench-computed.mjs",
  "methods" : "./workbench-methods.mjs",
  "mixins" : [
    "./workbench-source-tree.mjs",
    "./workbench-global-imports.mjs",
    "./workbench.mjs"],
  "components": [
    "./head",
    "./com/wb-source-tree",
    "./com/wb-imports",
    "./com/wb-arena",
    "./com/wb-mcu",
    "./com/wb-devices"
  ]
});
//========================================
// JOIN <m-my-buildsrv-actions.mjs> mod/buildsrv/m-my-buildsrv-actions.mjs
//========================================
Ti.Preload("mod/buildsrv/m-my-buildsrv-actions.mjs", TI_PACK_EXPORTS['mod/buildsrv/m-my-buildsrv-actions.mjs']);
//========================================
// JOIN <m-my-buildsrv-methods.mjs> mod/buildsrv/m-my-buildsrv-methods.mjs
//========================================
Ti.Preload("mod/buildsrv/m-my-buildsrv-methods.mjs", TI_PACK_EXPORTS['mod/buildsrv/m-my-buildsrv-methods.mjs']);
//========================================
// JOIN <m-my-buildsrv.json> mod/buildsrv/m-my-buildsrv.json
//========================================
Ti.Preload("mod/buildsrv/m-my-buildsrv.json", {
  "buildMetas": [],
  "buildFonts": [],
  "myBuildList": [],
  "currentBuildId": null,
  "currentBuild": null,
  "currentBuildConf": null,
  "currentBuildDataFile": null,
  "currentBuildDest": null,
  "currentBuildLog": null,
  "currentBuildSize": 0,
  "currentMaxBuildSize": 0,
  "__saved_currentBuildConf": null,
  "status": {
    "changed": false,
    "saving": false,
    "reloading": false
  }
});
//========================================
// JOIN <m-my-buildsrv.mjs> mod/buildsrv/m-my-buildsrv.mjs
//========================================
Ti.Preload("mod/buildsrv/m-my-buildsrv.mjs", TI_PACK_EXPORTS['mod/buildsrv/m-my-buildsrv.mjs']);
//========================================
// JOIN <_mod.json> mod/buildsrv/_mod.json
//========================================
Ti.Preload("mod/buildsrv/_mod.json", {
  "name": "minke-my-buildsrv",
  "namespaced": true,
  "state": "./m-my-buildsrv.json",
  "actions": [
    "./m-my-buildsrv-methods.mjs",
    "./m-my-buildsrv-actions.mjs"
  ],
  "mixins": "./m-my-buildsrv.mjs"
});
//========================================
// JOIN <minke-util.mjs> mod/minke-util.mjs
//========================================
Ti.Preload("mod/minke-util.mjs", TI_PACK_EXPORTS['mod/minke-util.mjs']);
//========================================
// JOIN <m-my-workbench-actions.mjs> mod/workbench/m-my-workbench-actions.mjs
//========================================
Ti.Preload("mod/workbench/m-my-workbench-actions.mjs", TI_PACK_EXPORTS['mod/workbench/m-my-workbench-actions.mjs']);
//========================================
// JOIN <m-my-workbench-gencode.mjs> mod/workbench/m-my-workbench-gencode.mjs
//========================================
Ti.Preload("mod/workbench/m-my-workbench-gencode.mjs", TI_PACK_EXPORTS['mod/workbench/m-my-workbench-gencode.mjs']);
//========================================
// JOIN <m-my-workbench-methods.mjs> mod/workbench/m-my-workbench-methods.mjs
//========================================
Ti.Preload("mod/workbench/m-my-workbench-methods.mjs", TI_PACK_EXPORTS['mod/workbench/m-my-workbench-methods.mjs']);
//========================================
// JOIN <m-my-workbench.json> mod/workbench/m-my-workbench.json
//========================================
Ti.Preload("mod/workbench/m-my-workbench.json", {
  "myProjects": [],
  "currentProjId": null,
  "currentProject": null,
  "currentProjectFiles": null,
  "currentFileId": null,
  "currentFile": null,
  "currentFileContent": null,
  "__saved_currentFileContent": null,
  "list": [],
  "currentId": null,
  "checkedIds": {},
  "status" : {
    "changed"   : false,
    "saving"    : false,
    "reloading" : false
  }
});
//========================================
// JOIN <m-my-workbench.mjs> mod/workbench/m-my-workbench.mjs
//========================================
Ti.Preload("mod/workbench/m-my-workbench.mjs", TI_PACK_EXPORTS['mod/workbench/m-my-workbench.mjs']);
//========================================
// JOIN <_mod.json> mod/workbench/_mod.json
//========================================
Ti.Preload("mod/workbench/_mod.json", {
  "name": "minke-my-workbench",
  "namespaced": true,
  "state": "./m-my-workbench.json",
  "actions": [
    "./m-my-workbench-methods.mjs",
    "./m-my-workbench-actions.mjs",
    "./m-my-workbench-gencode.mjs"
  ],
  "mixins": "./m-my-workbench.mjs"
});
//========================================
// JOIN <all.i18n.json> i18n/en-us/all.i18n.json
//========================================
Ti.Preload("i18n/en-us/all.i18n.json", {
  "lu-nav-home": "Home",
  "lu-nav-doc": "WIKI",
  "lu-nav-down": "Download",
  "lu-nav-blog": "Blog",
  "lu-nav-about": "About",
  "lu-nav-workbench": "Workbench",
  "lu-nav-devices": "Devices",
  "lu-nav-build": "Build",
  "lu-login-tip": "LoginName/Phone/Email",
  "lu-home-head-t0": "NEXT GENERATION EMBEDDED OS FOR IOT",
  "lu-home-head-t1": "SMALLER AND FASTER\nLOW POWER COST, LONG LIFE\nTHE LOWEST LEVEL OF EXPANSION",
  "lu-home-head-t2": "OUT OF THE BOX WITH \n AGILE DEVELOPMENT \n MOST EFFICIENT SCRIPTING SOLUTION",
  "lu-home-fea-t0": "A minimum of 32k ram, \n96k flash",
  "lu-home-fea-t1": "Optimized resource scheduling\nULP and long live",
  "lu-home-fea-t2": "Built-in Online Upgrade\nClippable and expandable",
  "lu-home-sec-title-2": "Powserful built-in function to support most IOT scenarios",
  "lu-home-it-sensor": "Sensor",
  "lu-home-it-pe": "PCI",
  "lu-home-sec-title-3": "More built-in features",
  "lu-home-sec-title-4": "You can expand infinitely if necessary",
  "lu-home-sec-title-5": "We will support more and more chip models for you",
  "lu-home-sec-title-6": "Gitee most valuable open source project - GVP",
  "lu-foot-slogan": "Lower cost, more robust",
  "lvgl-event-CLICKED": "Click",
  "lvgl-event-PRESSED": "Press",
  "lvgl-event-PRESSING": "Pressing",
  "lvgl-event-PRESS_LOST": "Press lost",
  "lvgl-event-SHORT_CLICKED": "Tap",
  "lvgl-event-LONG_PRESSED": "Long press",
  "lvgl-event-LONG_PRESSED_REPEAT": "Repeat",
  "lvgl-event-RELEASED": "Release",
  "lvgl-event-VALUE_CHANGED": "Change",
  "lvgl-event-KEY_UP": "Key up",
  "lvgl-event-KEY_RIGHT": "Key right",
  "lvgl-event-KEY_DOWN": "Key down",
  "lvgl-event-KEY_LEFT": "Key left",
  "lvgl-event-KEY_ENTER": "Key enter",
  "lvgl-event-INSERT": "Insert text",
  "lvgl-event-APPLY": "Insert Enter",
  "lvgl-event-CANCEL": "Insert Cancel"
});
//========================================
// JOIN <all.i18n.json> i18n/zh-cn/all.i18n.json
//========================================
Ti.Preload("i18n/zh-cn/all.i18n.json", {
  "lu-nav-home": "首页",
  "lu-nav-doc": "WIKI",
  "lu-nav-down": "下载",
  "lu-nav-blog": "博客",
  "lu-nav-about": "关于",
  "lu-nav-workbench": "工作台",
  "lu-nav-devices": "设备",
  "lu-nav-build": "构建",
  "lu-login-tip": "登录名/手机号/邮箱",
  "lu-home-head-t0": "下一代物联网嵌入式操作系统",
  "lu-home-head-t1": "更小更快\n低功耗长续航\n最底层的扩展能力",
  "lu-home-head-t2": "开箱即用\n业务逻辑快速完成\n最高效的脚本解决方案",
  "lu-home-fea-t0": "最低32k ram, \n96k flash",
  "lu-home-fea-t1": "优化资源调度策略\n超低功耗长时间运行",
  "lu-home-fea-t2": "内置在线升级\n可裁剪,可扩展",
  "lu-home-sec-title-2": "内置的功能足够支持绝大多数物联网场景",
  "lu-home-it-sensor": "传感器",
  "lu-home-it-pe": "外设",
  "lu-home-sec-title-3": "查看更多的内置功能",
  "lu-home-sec-title-4": "如果必要，你可以无限扩展",
  "lu-home-sec-title-5": "我们会为你支持越来越多精挑细选出的芯片型号",
  "lu-home-sec-title-6": "码云最有价值开源项目 - GVP",
  "lu-foot-slogan": "更低的成本，更稳健的物联网",
  "lvgl-event-CLICKED": "单击",
  "lvgl-event-PRESSED": "按下",
  "lvgl-event-PRESSING": "按住",
  "lvgl-event-PRESS_LOST": "取消按下",
  "lvgl-event-SHORT_CLICKED": "轻击",
  "lvgl-event-LONG_PRESSED": "长按",
  "lvgl-event-LONG_PRESSED_REPEAT": "持续长按",
  "lvgl-event-RELEASED": "抬起",
  "lvgl-event-VALUE_CHANGED": "改变",
  "lvgl-event-KEY_UP": "键盘上箭头",
  "lvgl-event-KEY_RIGHT": "键盘右箭头",
  "lvgl-event-KEY_DOWN": "键盘下箭头",
  "lvgl-event-KEY_LEFT": "键盘左箭头",
  "lvgl-event-KEY_ENTER": "键盘回车",
  "lvgl-event-INSERT": "文字插入",
  "lvgl-event-APPLY": "回车",
  "lvgl-event-CANCEL": "取消"
});
//////////////////////////////////////////////////
// The End
})();